func (c *Controller) Login() (string, error) { var pool_tech_works int funcMap := template.FuncMap{ "noescape": func(s string) template.HTML { return template.HTML(s) }, } data, err := static.Asset("static/templates/login.html") if err != nil { return "", err } modal, err := static.Asset("static/templates/modal.html") if err != nil { return "", err } t := template.Must(template.New("template").Funcs(funcMap).Parse(string(data))) t = template.Must(t.Parse(string(modal))) b := new(bytes.Buffer) // есть ли установочный пароль и был ли начально записан ключ var setupPassword bool if !c.Community { setupPassword_, err := c.Single("SELECT setup_password FROM config").String() if err != nil { return "", err } myKey, err := c.GetMyPublicKey(c.MyPrefix) if err != nil { return "", err } if len(myKey) == 0 && (len(setupPassword_) > 0 || setupPassword_ == string(utils.DSha256(""))) { setupPassword = true } } //fmt.Println(c.Lang) // проверим, не идут ли тех. работы на пуле if len(c.NodeConfig["pool_admin_user_id"]) > 0 && c.NodeConfig["pool_admin_user_id"] != utils.Int64ToStr(c.UserId) && c.NodeConfig["pool_tech_works"] == "1" && c.Community { pool_tech_works = 1 } else { pool_tech_works = 0 } err = t.ExecuteTemplate(b, "login", &loginStruct{ Lang: c.Lang, MyModalIdName: "myModalLogin", UserID: c.UserId, PoolTechWorks: pool_tech_works, SetupPassword: setupPassword, Community: c.Community, Desktop: utils.Desktop(), Mobile: utils.Mobile()}) if err != nil { return "", err } return b.String(), nil }
func ConfigInit() { // мониторим config.ini на наличие изменений go func() { for { log.Debug("ConfigInit monitor") if _, err := os.Stat(*utils.Dir + "/config.ini"); os.IsNotExist(err) { utils.Sleep(1) continue } 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 { break } utils.Sleep(3) } }() globalLangReadOnly = make(map[int]map[string]string) for _, v := range consts.LangMap { data, err := static.Asset(fmt.Sprintf("static/lang/%d.ini", v)) if err != nil { log.Error("%v", utils.ErrInfo(err)) } iniconf_, err := config.NewConfigData("ini", []byte(data)) if err != nil { log.Error("%v", utils.ErrInfo(err)) } //fmt.Println(iniconf_) iniconf, err := iniconf_.GetSection("default") globalLangReadOnly[v] = make(map[string]string) globalLangReadOnly[v] = iniconf } }
func BlocksCollection(chBreaker chan bool, chAnswer chan string) { defer func() { if r := recover(); r != nil { log.Error("daemon Recovered", r) panic(r) } }() const GoroutineName = "BlocksCollection" 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 = 300 } else { d.sleepTime = 60 } if !d.CheckInstall(chBreaker, chAnswer, GoroutineName) { return } d.DCDB = DbConnect(chBreaker, chAnswer, GoroutineName) if d.DCDB == nil { return } //var cur bool BEGIN: for { log.Info(GoroutineName) MonitorDaemonCh <- []string{GoroutineName, utils.Int64ToStr(utils.Time())} // проверим, не нужно ли нам выйти из цикла if CheckDaemonsRestart(chBreaker, chAnswer, GoroutineName) { break BEGIN } log.Debug("0") config, err := d.GetNodeConfig() if err != nil { if d.dPrintSleep(err, d.sleepTime) { break BEGIN } continue BEGIN } log.Debug("1") err, restart := d.dbLock() if restart { log.Debug("restart true") break BEGIN } if err != nil { log.Debug("restart err %v", err) if d.dPrintSleep(err, d.sleepTime) { break BEGIN } continue BEGIN } log.Debug("2") // если это первый запуск во время инсталяции currentBlockId, err := d.GetBlockId() if err != nil { if d.unlockPrintSleep(err, d.sleepTime) { break BEGIN } continue BEGIN } log.Info("config", config) log.Info("currentBlockId", currentBlockId) // на время тестов /*if !cur { currentBlockId = 0 cur = true }*/ parser := new(dcparser.Parser) parser.DCDB = d.DCDB parser.GoroutineName = GoroutineName if currentBlockId == 0 || *utils.StartBlockId > 0 { /* IsNotExistBlockChain := false if _, err := os.Stat(*utils.Dir+"/public/blockchain"); os.IsNotExist(err) { IsNotExistBlockChain = true }*/ if config["first_load_blockchain"] == "file" /* && IsNotExistBlockChain*/ { log.Info("first_load_blockchain=file") nodeConfig, err := d.GetNodeConfig() blockchain_url := nodeConfig["first_load_blockchain_url"] if len(blockchain_url) == 0 { blockchain_url = consts.BLOCKCHAIN_URL } log.Debug("blockchain_url: %s", blockchain_url) // возможно сервер отдаст блокчейн не с первой попытки var blockchainSize int64 for i := 0; i < 10; i++ { log.Debug("blockchain_url: %s, i: %d", blockchain_url, i) blockchainSize, err = utils.DownloadToFile(blockchain_url, *utils.Dir+"/public/blockchain", 3600, chBreaker, chAnswer, GoroutineName) if err != nil { log.Error("%v", utils.ErrInfo(err)) } if blockchainSize > consts.BLOCKCHAIN_SIZE { break } } log.Debug("blockchain dw ok") if err != nil || blockchainSize < consts.BLOCKCHAIN_SIZE { if err != nil { log.Error("%v", utils.ErrInfo(err)) } else { log.Info(fmt.Sprintf("%v < %v", blockchainSize, consts.BLOCKCHAIN_SIZE)) } if d.unlockPrintSleep(err, d.sleepTime) { break BEGIN } continue BEGIN } first := true /*// блокчейн мог быть загружен ранее. проверим его размер stat, err := file.Stat() if err != nil { if d.unlockPrintSleep(err, d.sleepTime) { break BEGIN } file.Close() continue BEGIN } if stat.Size() < consts.BLOCKCHAIN_SIZE { d.unlockPrintSleep(fmt.Errorf("%v < %v", stat.Size(), consts.BLOCKCHAIN_SIZE), 1) file.Close() continue BEGIN }*/ log.Debug("GO!") file, err := os.Open(*utils.Dir + "/public/blockchain") if err != nil { if d.unlockPrintSleep(err, d.sleepTime) { break BEGIN } continue BEGIN } err = d.ExecSql(`UPDATE config SET current_load_blockchain = 'file'`) if err != nil { if d.unlockPrintSleep(err, d.sleepTime) { break BEGIN } continue BEGIN } for { // проверим, не нужно ли нам выйти из цикла if CheckDaemonsRestart(chBreaker, chAnswer, GoroutineName) { d.unlockPrintSleep(fmt.Errorf("DaemonsRestart"), 0) break BEGIN } b1 := make([]byte, 5) file.Read(b1) dataSize := utils.BinToDec(b1) log.Debug("dataSize", dataSize) if dataSize > 0 { data := make([]byte, dataSize) file.Read(data) //log.Debug("data %x\n", data) blockId := utils.BinToDec(data[0:5]) if *utils.EndBlockId > 0 && blockId == *utils.EndBlockId { if d.dPrintSleep(err, d.sleepTime) { break BEGIN } file.Close() continue BEGIN } log.Info("blockId", blockId) data2 := data[5:] length := utils.DecodeLength(&data2) log.Debug("length", length) //log.Debug("data2 %x\n", data2) blockBin := utils.BytesShift(&data2, length) //log.Debug("blockBin %x\n", blockBin) if *utils.StartBlockId == 0 || (*utils.StartBlockId > 0 && blockId > *utils.StartBlockId) { // парсинг блока parser.BinaryData = blockBin if first { parser.CurrentVersion = consts.VERSION first = false } err = parser.ParseDataFull() if err != nil { if d.dPrintSleep(err, d.sleepTime) { break BEGIN } file.Close() continue BEGIN } err = parser.InsertIntoBlockchain() if err != nil { if d.dPrintSleep(err, d.sleepTime) { break BEGIN } file.Close() continue BEGIN } // отметимся, чтобы не спровоцировать очистку таблиц err = parser.UpdMainLock() if err != nil { if d.dPrintSleep(err, d.sleepTime) { break BEGIN } file.Close() continue BEGIN } if CheckDaemonsRestart(chBreaker, chAnswer, GoroutineName) { if d.dPrintSleep(err, d.sleepTime) { break BEGIN } file.Close() continue BEGIN } } // ненужный тут размер в конце блока данных data = make([]byte, 5) file.Read(data) } else { if d.unlockPrintSleep(err, d.sleepTime) { break BEGIN } continue BEGIN } // utils.Sleep(1) } file.Close() } else { newBlock, err := static.Asset("static/1block.bin") if err != nil { if d.dPrintSleep(err, d.sleepTime) { break BEGIN } continue BEGIN } parser.BinaryData = newBlock parser.CurrentVersion = consts.VERSION err = parser.ParseDataFull() if err != nil { if d.dPrintSleep(err, d.sleepTime) { break BEGIN } continue BEGIN } err = parser.InsertIntoBlockchain() if err != nil { if d.dPrintSleep(err, d.sleepTime) { break BEGIN } continue BEGIN } } utils.Sleep(1) d.dbUnlock() continue BEGIN } d.dbUnlock() err = d.ExecSql(`UPDATE config SET current_load_blockchain = 'nodes'`) if err != nil { if d.unlockPrintSleep(err, d.sleepTime) { break BEGIN } continue BEGIN } myConfig, err := d.OneRow("SELECT local_gate_ip, static_node_user_id FROM config").String() if err != nil { if d.dPrintSleep(err, d.sleepTime) { break BEGIN } continue } var hosts []map[string]string var nodeHost string var dataTypeMaxBlockId, dataTypeBlockBody int64 if len(myConfig["local_gate_ip"]) > 0 { hosts = append(hosts, map[string]string{"host": myConfig["local_gate_ip"], "user_id": myConfig["static_node_user_id"]}) nodeHost, err = d.Single("SELECT tcp_host FROM miners_data WHERE user_id = ?", myConfig["static_node_user_id"]).String() if err != nil { if d.dPrintSleep(err, d.sleepTime) { break BEGIN } continue } dataTypeMaxBlockId = 9 dataTypeBlockBody = 8 //getBlockScriptName = "ajax?controllerName=protectedGetBlock"; //addNodeHost = "&nodeHost="+nodeHost; } else { // получим список нодов, с кем установлено рукопожатие hosts, err = d.GetAll("SELECT * FROM nodes_connection", -1) if err != nil { if d.dPrintSleep(err, d.sleepTime) { break BEGIN } continue } dataTypeMaxBlockId = 10 dataTypeBlockBody = 7 //getBlockScriptName = "ajax?controllerName=getBlock"; //addNodeHost = ""; } log.Info("%v", hosts) if len(hosts) == 0 { if d.dPrintSleep(err, 1) { break BEGIN } continue } maxBlockId := int64(1) maxBlockIdHost := "" var maxBlockIdUserId int64 // получим максимальный номер блока for i := 0; i < len(hosts); i++ { if CheckDaemonsRestart(chBreaker, chAnswer, GoroutineName) { break BEGIN } conn, err := utils.TcpConn(hosts[i]["host"]) if err != nil { if d.dPrintSleep(err, 1) { break BEGIN } continue } // шлем тип данных _, err = conn.Write(utils.DecToBin(dataTypeMaxBlockId, 1)) if err != nil { conn.Close() if d.dPrintSleep(err, 1) { break BEGIN } continue } if len(nodeHost) > 0 { // защищенный режим err = utils.WriteSizeAndData([]byte(nodeHost), conn) if err != nil { conn.Close() if d.dPrintSleep(err, d.sleepTime) { break BEGIN } continue } } // в ответ получаем номер блока blockIdBin := make([]byte, 4) _, err = conn.Read(blockIdBin) if err != nil { conn.Close() if d.dPrintSleep(err, 1) { break BEGIN } continue } conn.Close() id := utils.BinToDec(blockIdBin) if id > maxBlockId || i == 0 { maxBlockId = id maxBlockIdHost = hosts[i]["host"] maxBlockIdUserId = utils.StrToInt64(hosts[i]["user_id"]) } if CheckDaemonsRestart(chBreaker, chAnswer, GoroutineName) { utils.Sleep(1) break BEGIN } } // получим наш текущий имеющийся номер блока // ждем, пока разлочится и лочим сами, чтобы не попасть в тот момент, когда данные из блока уже занесены в БД, а info_block еще не успел обновиться err, restart = d.dbLock() if restart { break BEGIN } if err != nil { if d.dPrintSleep(err, d.sleepTime) { break BEGIN } continue BEGIN } currentBlockId, err = d.Single("SELECT block_id FROM info_block").Int64() if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue } log.Info("currentBlockId", currentBlockId, "maxBlockId", maxBlockId) if maxBlockId <= currentBlockId { if d.unlockPrintSleep(utils.ErrInfo(errors.New("maxBlockId <= currentBlockId")), d.sleepTime) { break BEGIN } continue } fmt.Printf("\nnode: %s\n", maxBlockIdHost) // в цикле собираем блоки, пока не дойдем до максимального for blockId := currentBlockId + 1; blockId < maxBlockId+1; blockId++ { d.UpdMainLock() if CheckDaemonsRestart(chBreaker, chAnswer, GoroutineName) { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } break BEGIN } variables, err := d.GetAllVariables() if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } // качаем тело блока с хоста maxBlockIdHost binaryBlock, err := utils.GetBlockBody(maxBlockIdHost, blockId, dataTypeBlockBody, nodeHost) if len(binaryBlock) == 0 { // баним на 1 час хост, который дал нам пустой блок, хотя должен был дать все до максимального // для тестов убрал, потом вставить. //nodes_ban ($db, $max_block_id_user_id, substr($binary_block, 0, 512)."\n".__FILE__.', '.__LINE__.', '. __FUNCTION__.', '.__CLASS__.', '. __METHOD__); //p.NodesBan(maxBlockIdUserId, "len(binaryBlock) == 0") if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } binaryBlockFull := binaryBlock utils.BytesShift(&binaryBlock, 1) // уберем 1-й байт - тип (блок/тр-я) // распарсим заголовок блока blockData := utils.ParseBlockHeader(&binaryBlock) log.Info("blockData: %v, blockId: %v", blockData, blockId) // если существуют глючная цепочка, тот тут мы её проигнорируем badBlocks_, err := d.Single("SELECT bad_blocks FROM config").Bytes() if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } badBlocks := make(map[int64]string) if len(badBlocks_) > 0 { err = json.Unmarshal(badBlocks_, &badBlocks) if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } } if badBlocks[blockData.BlockId] == string(utils.BinToHex(blockData.Sign)) { d.NodesBan(maxBlockIdUserId, fmt.Sprintf("bad_block = %v => %v", blockData.BlockId, badBlocks[blockData.BlockId])) if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } // размер блока не может быть более чем max_block_size if currentBlockId > 1 { if int64(len(binaryBlock)) > variables.Int64["max_block_size"] { d.NodesBan(maxBlockIdUserId, fmt.Sprintf(`len(binaryBlock) > variables.Int64["max_block_size"] %v > %v`, len(binaryBlock), variables.Int64["max_block_size"])) if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } } if blockData.BlockId != blockId { d.NodesBan(maxBlockIdUserId, fmt.Sprintf(`blockData.BlockId != blockId %v > %v`, blockData.BlockId, blockId)) if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } // нам нужен хэш предыдущего блока, чтобы проверить подпись prevBlockHash := "" if blockId > 1 { prevBlockHash, err = d.Single("SELECT hash FROM block_chain WHERE id = ?", blockId-1).String() if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } prevBlockHash = string(utils.BinToHex([]byte(prevBlockHash))) } else { prevBlockHash = "0" } first := false if blockId == 1 { first = true } // нам нужен меркель-рут текущего блока mrklRoot, err := utils.GetMrklroot(binaryBlock, variables, first) if err != nil { d.NodesBan(maxBlockIdUserId, fmt.Sprintf(`%v`, err)) if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } // публичный ключ того, кто этот блок сгенерил nodePublicKey, err := d.GetNodePublicKey(blockData.UserId) if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } // SIGN от 128 байта до 512 байт. Подпись от TYPE, BLOCK_ID, PREV_BLOCK_HASH, TIME, USER_ID, LEVEL, MRKL_ROOT forSign := fmt.Sprintf("0,%v,%v,%v,%v,%v,%s", blockData.BlockId, prevBlockHash, blockData.Time, blockData.UserId, blockData.Level, mrklRoot) // проверяем подпись if !first { _, err = utils.CheckSign([][]byte{nodePublicKey}, forSign, blockData.Sign, true) } // качаем предыдущие блоки до тех пор, пока отличается хэш предыдущего. // другими словами, пока подпись с prevBlockHash будет неверной, т.е. пока что-то есть в $error if err != nil { log.Error("%v", utils.ErrInfo(err)) if blockId < 1 { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } // нужно привести данные в нашей БД в соответствие с данными у того, у кого качаем более свежий блок //func (p *Parser) GetOldBlocks (userId, blockId int64, host string, hostUserId int64, goroutineName, getBlockScriptName, addNodeHost string) error { err := parser.GetOldBlocks(blockData.UserId, blockId-1, maxBlockIdHost, maxBlockIdUserId, GoroutineName, dataTypeBlockBody, nodeHost) if err != nil { log.Error("%v", err) d.NodesBan(maxBlockIdUserId, fmt.Sprintf(`blockId: %v / %v`, blockId, err)) if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } } else { log.Info("plug found blockId=%v\n", blockId) // получим наши транзакции в 1 бинарнике, просто для удобства var transactions []byte utils.WriteSelectiveLog("SELECT data FROM transactions WHERE verified = 1 AND used = 0") rows, err := d.Query("SELECT data FROM transactions WHERE verified = 1 AND used = 0") if err != nil { utils.WriteSelectiveLog(err) if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } for rows.Next() { var data []byte err = rows.Scan(&data) utils.WriteSelectiveLog(utils.BinToHex(data)) if err != nil { rows.Close() if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } transactions = append(transactions, utils.EncodeLengthPlusData(data)...) } rows.Close() if len(transactions) > 0 { // отмечаем, что эти тр-ии теперь нужно проверять по новой utils.WriteSelectiveLog("UPDATE transactions SET verified = 0 WHERE verified = 1 AND used = 0") affect, err := d.ExecSqlGetAffect("UPDATE transactions SET verified = 0 WHERE verified = 1 AND used = 0") if err != nil { utils.WriteSelectiveLog(err) if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } utils.WriteSelectiveLog("affect: " + utils.Int64ToStr(affect)) // откатываем по фронту все свежие тр-ии parser.BinaryData = transactions err = parser.ParseDataRollbackFront(false) if err != nil { utils.Sleep(1) continue BEGIN } } err = parser.RollbackTransactionsTestblock(true) if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } err = d.ExecSql("DELETE FROM testblock") if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } } // теперь у нас в таблицах всё тоже самое, что у нода, у которого качаем блок // и можем этот блок проверить и занести в нашу БД parser.BinaryData = binaryBlockFull err = parser.ParseDataFull() if err == nil { err = parser.InsertIntoBlockchain() if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } } // начинаем всё с начала уже с другими нодами. Но у нас уже могут быть новые блоки до $block_id, взятые от нода, которого с в итоге мы баним if err != nil { d.NodesBan(maxBlockIdUserId, fmt.Sprintf(`blockId: %v / %v`, blockId, err)) if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } } d.dbUnlock() if d.dSleep(d.sleepTime) { break BEGIN } } log.Debug("break BEGIN %v", GoroutineName) }
func 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) }
func IndexCf(w http.ResponseWriter, r *http.Request) { nav := "" if len(r.URL.RawQuery) > 0 { re, _ := regexp.Compile(`category\-([0-9]+)`) match := re.FindStringSubmatch(r.URL.RawQuery) if len(match) > 0 { nav = "dc_navigate ('cfCatalog', {'category_id':" + match[1] + "})\n" } else { re, _ := regexp.Compile(`([A-Z0-9]{7}|id-[0-9]+)\-?([0-9]+)?\-?(funders|comments|news|home|payment)?`) match0 := re.FindStringSubmatch(r.URL.RawQuery) if len(match0) > 1 { // $m[1] - название валюты или id валюты // $m[2] - id языка // $m[3] - тип страницы (funders|comments|news) addNav := "" re, _ := regexp.Compile(`id\-([0-9]+)`) match := re.FindStringSubmatch(match0[1]) if len(match) > 1 { addNav += "'onlyProjectId':'" + match[1] + "'," } else { addNav += "'onlyCfCurrencyName':'" + match[1] + "'," } if len(match0) > 2 { addNav += "'lang_id':'" + match0[2] + "'," } if len(match0) > 3 { addNav += "'page':'" + match0[3] + "'," } addNav = addNav[:len(addNav)-1] nav = "dc_navigate ('cfPagePreview', {" + addNav + "})\n" } } } else { nav = "dc_navigate ('cfCatalog')\n" } log.Debug(nav) 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() cfLang, err := c.GetAllCfLng() r.ParseForm() c.Parameters, err = c.GetParameters() log.Debug("parameters=", c.Parameters) lang := GetLang(w, r, c.Parameters) analyticsDisabled, err := utils.DB.Single(`SELECT analytics_disabled FROM config`).String() if err != nil { log.Error("%v", err) } data, err := static.Asset("static/templates/index_cf.html") t := template.New("template") t, err = t.Parse(string(data)) if err != nil { log.Error("%v", err) } b := new(bytes.Buffer) t.Execute(b, &indexCf{CfUrl: cfUrl, Lang: utils.IntToStr(lang), Nav: template.JS(nav), CfLang: cfLang, AnalyticsDisabled: analyticsDisabled}) w.Write(b.Bytes()) } }
func Index(w http.ResponseWriter, r *http.Request) { r.ParseForm() parameters_ := make(map[string]interface{}) err := json.Unmarshal([]byte(r.PostFormValue("parameters")), ¶meters_) if err != nil { log.Error("%v", err) } log.Debug("parameters_=%", parameters_) parameters := make(map[string]string) for k, v := range parameters_ { parameters[k] = utils.InterfaceToStr(v) } lang := GetLang(w, r, parameters) sess, err := globalSessions.SessionStart(w, r) if err != nil { log.Error("%v", err) } defer sess.SessionRelease(w) sessUserId := GetSessUserId(sess) var key, myPrefix, status string var communityUsers []int64 var chatEnabled, analyticsDisabled string if utils.DB != nil && utils.DB.DB != nil { communityUsers, err = utils.DB.GetCommunityUsers() if err != nil { log.Error("%v", err) } if len(communityUsers) > 0 { myPrefix = utils.Int64ToStr(sessUserId) + "_" } status, err := utils.DB.Single("SELECT status FROM " + myPrefix + "my_table").String() // чтобы нельзя было зайти по локалке // :: - для маков if ok, _ := regexp.MatchString(`(\:\:)|(127\.0\.0\.1)`, r.RemoteAddr); ok { if status != "waiting_accept_new_key" && status != "waiting_set_new_key" { key, err = utils.DB.Single("SELECT private_key FROM " + myPrefix + "my_keys WHERE block_id = (SELECT max(block_id) FROM " + myPrefix + "my_keys)").String() if err != nil { log.Error("%v", err) } } } chatEnabled, err = utils.DB.Single(`SELECT chat_enabled FROM config`).String() if err != nil { log.Error("%v", err) } analyticsDisabled, err = utils.DB.Single(`SELECT analytics_disabled FROM config`).String() if err != nil { log.Error("%v", err) } } showIOSMenu := true // Когда меню не выдаем if utils.DB == nil || utils.DB.DB == nil { showIOSMenu = false } else { if status == "my_pending" { showIOSMenu = false } } if sessUserId == 0 { showIOSMenu = false } if showIOSMenu && utils.DB != nil && utils.DB.DB != nil { blockData, err := utils.DB.GetInfoBlock() if err != nil { log.Error("%v", err) } wTime := int64(12) wTimeReady := int64(2) log.Debug("wTime: %v / utils.Time(): %v / blockData[time]: %v", wTime, utils.Time(), utils.StrToInt64(blockData["time"])) // если время менее 12 часов от текущего, то выдаем не подвержденные, а просто те, что есть в блокчейне if utils.Time()-utils.StrToInt64(blockData["time"]) < 3600*wTime { lastBlockData, err := utils.DB.GetLastBlockData() if err != nil { log.Error("%v", err) } log.Debug("lastBlockData[lastBlockTime]: %v", lastBlockData["lastBlockTime"]) log.Debug("time.Now().Unix(): %v", utils.Time()) if utils.Time()-lastBlockData["lastBlockTime"] >= 3600*wTimeReady { showIOSMenu = false } } else { showIOSMenu = false } } if showIOSMenu && !utils.Mobile() { showIOSMenu = false } mobile := utils.Mobile() if ok, _ := regexp.MatchString("(?i)(iPod|iPhone|iPad|Android)", r.UserAgent()); ok { mobile = true } ios := utils.IOS() if ok, _ := regexp.MatchString("(?i)(iPod|iPhone|iPad)", r.UserAgent()); ok { ios = true } android := utils.Android() if ok, _ := regexp.MatchString("(?i)(Android)", r.UserAgent()); ok { android = true } var upgrade3 string if len(r.FormValue("upgrade3")) > 0 { upgrade3 = "1" } var upgrade4 string if len(r.FormValue("upgrade4")) > 0 { upgrade4 = "1" } formKey := r.FormValue("key") if len(formKey) > 0 { key = formKey // пишем в сессию, что бы ctrl+F5 не сбрасывал ключ (для авто-входа с dcoin.club) sess.Set("private_key", key) } else if len(key) == 0 { key = GetSessPrivateKey(w, r) } key = strings.Replace(key, "\r", "\n", -1) key = strings.Replace(key, "\n\n", "\n", -1) key = strings.Replace(key, "\n", "\\\n", -1) setLang := r.FormValue("lang") data, err := static.Asset("static/templates/index.html") t := template.New("template") t, err = t.Parse(string(data)) if err != nil { log.Error("%v", err) } b := new(bytes.Buffer) err = t.Execute(b, &index{ Upgrade3: upgrade3, Upgrade4: upgrade4, DbOk: true, Lang: globalLangReadOnly[lang], Key: key, SetLang: setLang, ShowIOSMenu: showIOSMenu, /*IOS: true, Android: false, Mobile: true})*/ IOS: ios, Android: android, ChatEnabled: chatEnabled, AnalyticsDisabled: analyticsDisabled, Mobile: mobile}) if err != nil { log.Error("%v", err) } w.Write(b.Bytes()) }
func IndexE(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() c.Parameters, err = c.GetParameters() log.Debug("parameters=", c.Parameters) lang := GetLang(w, r, c.Parameters) log.Debug("lang", lang) c.Lang = globalLangReadOnly[lang] var myWallets []map[string]string if c.SessUserId > 0 { myWallets, err = c.getMyWallets() if err != nil { w.Write([]byte(utils.ErrInfo(err).Error())) log.Error("%v", err) return } } c.EConfig, err = c.GetMap(`SELECT * FROM e_config`, "name", "value") if err != nil { log.Error("%v", err) } eHost := c.EConfig["domain"] if len(eHost) == 0 { http_host, err := c.Single(`SELECT http_host FROM config`).String() if err != nil { w.Write([]byte(utils.ErrInfo(err).Error())) log.Error("%v", err) return } re := regexp.MustCompile(`^https?:\/\/([0-9a-z\_\.\-:]+)\/?`) match := re.FindStringSubmatch(http_host) if len(match) != 0 { c.EConfig["catalog"] = strings.Replace(c.EConfig["catalog"], "/", "", -1) eHost = match[1] + "/" + c.EConfig["catalog"] + "/" } } analyticsDisabled, err := utils.DB.Single(`SELECT analytics_disabled FROM config`).String() if err != nil { log.Error("%v", err) } data, err := static.Asset("static/templates/index_e.html") if err != nil { w.Write([]byte(utils.ErrInfo(err).Error())) log.Error("%v", err) return } t := template.New("template") t, err = t.Parse(string(data)) if err != nil { w.Write([]byte(utils.ErrInfo(err).Error())) log.Error("%v", err) return } b := new(bytes.Buffer) err = t.Execute(b, &indexE{MyWallets: myWallets, Lang: c.Lang, UserId: c.SessUserId, EHost: eHost, AnalyticsDisabled: analyticsDisabled}) if err != nil { log.Error("%v", err) w.Write([]byte(utils.ErrInfo(err).Error())) } else { w.Write(b.Bytes()) } } }
func makeTemplate(html, name string, tData interface{}) (string, error) { defer func() { if r := recover(); r != nil { log.Error("makeTemplate Recovered", r) fmt.Println(r) } }() data, err := static.Asset("static/templates/" + html + ".html") if err != nil { return "", utils.ErrInfo(err) } signatures, err := static.Asset("static/templates/signatures.html") if err != nil { return "", utils.ErrInfo(err) } alert_success, err := static.Asset("static/templates/alert_success.html") if err != nil { return "", utils.ErrInfo(err) } funcMap := template.FuncMap{ "makeCurrencyName": func(currencyId int64) string { if currencyId >= 1000 { return "" } else { return "d" } }, "div": func(a, b interface{}) float64 { return utils.InterfaceToFloat64(a) / utils.InterfaceToFloat64(b) }, "mult": func(a, b interface{}) float64 { return utils.InterfaceToFloat64(a) * utils.InterfaceToFloat64(b) }, "round": func(a interface{}, num int) float64 { return utils.Round(utils.InterfaceToFloat64(a), num) }, "len": func(s []map[string]string) int { return len(s) }, "lenMap": func(s map[string]string) int { return len(s) }, "sum": func(a, b interface{}) float64 { return utils.InterfaceToFloat64(a) + utils.InterfaceToFloat64(b) }, "minus": func(a, b interface{}) float64 { return utils.InterfaceToFloat64(a) - utils.InterfaceToFloat64(b) }, "noescape": func(s string) template.HTML { return template.HTML(s) }, "js": func(s string) template.JS { return template.JS(s) }, "join": func(s []string, sep string) string { return strings.Join(s, sep) }, "strToInt64": func(text string) int64 { return utils.StrToInt64(text) }, "strToInt": func(text string) int { return utils.StrToInt(text) }, "bin2hex": func(text string) string { return string(utils.BinToHex([]byte(text))) }, "int64ToStr": func(text int64) string { return utils.Int64ToStr(text) }, "rand": func() int { return utils.RandInt(0, 99999999) }, "append": func(args ...interface{}) string { var result string for _, value := range args { switch value.(type) { case int64: result += utils.Int64ToStr(value.(int64)) case float64: result += utils.Float64ToStr(value.(float64)) case string: result += value.(string) } } return result }, "replaceCurrency": func(text, name string) string { return strings.Replace(text, "[currency]", name, -1) }, "replaceCurrencyName": func(text, name string) string { return strings.Replace(text, "[currency]", "D"+name, -1) }, "cfCategoryLang": func(lang map[string]string, name string) string { return lang["cf_category_"+name] }, "progressBarLang": func(lang map[string]string, name string) string { return lang["progress_bar_pct_"+name] }, "checkProjectPs": func(ProjectPs map[string]string, id string) bool { if len(ProjectPs["ps"+id]) > 0 { return true } else { return false } }, "cfPageTypeLang": func(lang map[string]string, name string) string { return lang["cf_"+name] }, "notificationsLang": func(lang map[string]string, name string) string { return lang["notifications_"+name] }, } t := template.Must(template.New("template").Funcs(funcMap).Parse(string(data))) t = template.Must(t.Parse(string(alert_success))) t = template.Must(t.Parse(string(signatures))) b := new(bytes.Buffer) err = t.ExecuteTemplate(b, name, tData) if err != nil { return "", utils.ErrInfo(err) } return b.String(), nil }
func main_loader(w http.ResponseWriter, r *http.Request) { data, _ := static.Asset("static/img/main_loader.gif") fmt.Fprint(w, string(data)) }
func (c *Controller) UpdatingBlockchain() (string, error) { var blockTime, blockId, blockMeter int64 var waitText, startDaemons, checkTime string var restartDb bool if c.dbInit { ConfirmedBlockId, err := c.DCDB.GetConfirmedBlockId() if err != nil { return "", utils.ErrInfo(err) } if ConfirmedBlockId == 0 { firstLoadBlockchain, err := c.DCDB.Single("SELECT first_load_blockchain FROM config").String() if err != nil { return "", utils.ErrInfo(err) } if firstLoadBlockchain == "file" { waitText = c.Lang["loading_blockchain_please_wait"] } else { waitText = c.Lang["is_synchronized_with_the_dc_network"] } } else { LastBlockData, err := c.DCDB.GetLastBlockData() if err != nil { return "", utils.ErrInfo(err) } blockTime = LastBlockData["lastBlockTime"] blockId = LastBlockData["blockId"] } // для сингл-мода, кнопка включения и выключения демонов if !c.Community { lockName, err := c.DCDB.GetMainLockName() if err != nil { return "", utils.ErrInfo(err) } if lockName == "main_lock" { startDaemons = `<a href="#" id="start_daemons" style="color:#C90600">Start daemons</a>` } // инфа о синхронизации часов switch runtime.GOOS { case "linux": checkTime = c.Lang["check_time_nix"] case "windows": checkTime = c.Lang["check_time_win"] case "darwin": checkTime = c.Lang["check_time_mac"] default: checkTime = c.Lang["check_time_nix"] } checkTime = c.Lang["check_time"] + checkTime mainLock, err := c.Single(`SELECT lock_time from main_lock`).Int64() if mainLock > 0 && utils.Time()-300 > mainLock { restartDb = true } } nodeConfig, err := c.GetNodeConfig() blockchain_url := nodeConfig["first_load_blockchain_url"] if len(blockchain_url) == 0 { blockchain_url = consts.BLOCKCHAIN_URL } resp, err := http.Get(blockchain_url) if err != nil { return "", utils.ErrInfo(err) } blockChainSize := resp.ContentLength if blockChainSize == 0 { blockChainSize = consts.BLOCKCHAIN_SIZE } defer resp.Body.Close() blockMeter = int64(utils.Round(float64((blockId/consts.LAST_BLOCK)*100), 0)) - 1 } else { waitText = c.Lang["loading_blockchain_please_wait"] } var mobile bool if utils.Mobile() { mobile = true } networkTime, err := utils.GetNetworkTime() if err != nil { return "", utils.ErrInfo(err) } diff := int64(math.Abs(float64(utils.Time() - networkTime.Unix()))) var alertTime string if c.dbInit && diff > c.Variables.Int64["alert_error_time"] { alertTime = strings.Replace(c.Lang["alert_time"], "[sec]", utils.Int64ToStr(diff), -1) } funcMap := template.FuncMap{ "noescape": func(s string) template.HTML { return template.HTML(s) }, } data, err := static.Asset("static/templates/updating_blockchain.html") t := template.New("template").Funcs(funcMap) t, err = t.Parse(string(data)) if err != nil { return "", utils.ErrInfo(err) } b := new(bytes.Buffer) t.Execute(b, &updatingBlockchainStruct{RestartDb: restartDb, Lang: c.Lang, WaitText: waitText, BlockId: blockId, BlockTime: blockTime, StartDaemons: startDaemons, BlockMeter: blockMeter, CheckTime: checkTime, LastBlock: consts.LAST_BLOCK, BlockChainSize: consts.BLOCKCHAIN_SIZE, Mobile: mobile, AlertTime: alertTime}) return b.String(), nil }
func (c *Controller) ProgressBar() (string, error) { if !c.dbInit { return "", nil } progressBarPct := make(map[string]int64) progressBarPct["begin"] = 10 progressBarPct["change_key"] = 10 progressBarPct["my_table"] = 5 progressBarPct["upgrade_country"] = 3 progressBarPct["upgrade_face_hash"] = 3 progressBarPct["upgrade_profile_hash"] = 3 progressBarPct["upgrade_face_coords"] = 3 progressBarPct["upgrade_profile_coords"] = 3 progressBarPct["upgrade_video"] = 3 progressBarPct["upgrade_host"] = 3 progressBarPct["upgrade_geolocation"] = 3 progressBarPct["promised_amount"] = 5 progressBarPct["commission"] = 3 progressBarPct["tasks"] = 8 progressBarPct["vote"] = 5 progressBarPct["referral"] = 1 progressBar := make(map[string]int64) // сменил ли юзер ключ changeKey, err := c.Single("SELECT log_id FROM users WHERE user_id = ?", c.SessUserId).Int64() if err != nil { return "", utils.ErrInfo(err) } last_tx, err := c.GetLastTx(c.SessUserId, utils.TypesToIds([]string{"ChangePrimaryKey"}), 1, c.TimeFormat) if err != nil { return "", utils.ErrInfo(err) } if (len(last_tx) > 0 && (len(last_tx[0]["queue_tx"]) > 0 || len(last_tx[0]["tx"]) > 0)) || changeKey > 0 { progressBar["change_key"] = 1 } // есть ли в БД личная юзерсая таблица if c.Community { tables, err := c.GetAllTables() if err != nil { return "", utils.ErrInfo(err) } if utils.InSliceString(utils.Int64ToStr(c.SessUserId)+"_my_table", tables) { progressBar["my_table"] = 1 } } else { progressBar["my_table"] = 1 } // апгрейд аккаунта myMinersId, err := c.GetMinerId(c.SessUserId) if myMinersId > 0 { progressBar["upgrade_country"] = 1 progressBar["upgrade_face_hash"] = 1 progressBar["upgrade_profile_hash"] = 1 progressBar["upgrade_face_coords"] = 1 progressBar["upgrade_profile_coords"] = 1 progressBar["upgrade_video"] = 1 progressBar["upgrade_host"] = 1 progressBar["upgrade_geolocation"] = 1 } else if c.SessRestricted == 0 { upgradeData, err := c.OneRow("SELECT user_id, race, country, geolocation, http_host as host, face_coords, profile_coords, video_url_id, video_type FROM " + c.MyPrefix + "my_table").String() if err != nil { return "", utils.ErrInfo(err) } if len(upgradeData["race"]) > 0 && len(upgradeData["country"]) > 0 { progressBar["upgrade_country"] = 1 } if len(upgradeData["face_hash"]) > 0 { progressBar["upgrade_face_hash"] = 1 } if len(upgradeData["profile_hash"]) > 0 { progressBar["upgrade_profile_hash"] = 1 } if len(upgradeData["face_coords"]) > 0 { progressBar["upgrade_face_coords"] = 1 } if len(upgradeData["profile_coords"]) > 0 { progressBar["upgrade_profile_coords"] = 1 } if _, err := os.Stat(*utils.Dir + "public/" + utils.Int64ToStr(c.SessUserId) + "_user_video.mp4"); os.IsExist(err) { if len(upgradeData["video_url_id"]) > 0 { progressBar["upgrade_video"] = 1 } } if len(upgradeData["host"]) > 0 { progressBar["upgrade_host"] = 1 } if len(upgradeData["latitude"]) > 0 && len(upgradeData["longitude"]) > 0 { progressBar["upgrade_geolocation"] = 1 } } // добавлена ли обещанная сумма promisedAmount, err := c.Single("SELECT id FROM promised_amount WHERE user_id = ?", c.SessUserId).Int64() if err != nil { return "", utils.ErrInfo(err) } // возможно юзер уже отправил запрос на добавление обещенной суммы last_tx, err = c.GetLastTx(c.SessUserId, utils.TypesToIds([]string{"NewPromisedAmount"}), 1, c.TimeFormat) if (len(last_tx) > 0 && (len(last_tx[0]["queue_tx"]) > 0 || len(last_tx[0]["tx"]) > 0)) || promisedAmount > 0 { progressBar["promised_amount"] = 1 } // установлена ли комиссия commission, err := c.Single("SELECT commission FROM commission WHERE user_id = ?", c.UserId).String() if err != nil { return "", utils.ErrInfo(err) } // возможно юзер уже отправил запрос на добавление комиссии last_tx, err = c.GetLastTx(c.SessUserId, utils.TypesToIds([]string{"ChangeCommission"}), 1, c.TimeFormat) if (len(last_tx) > 0 && (len(last_tx[0]["queue_tx"]) > 0 || len(last_tx[0]["tx"]) > 0)) || len(commission) > 0 { progressBar["commission"] = 1 } // голосование за параметры валют. для простоты смотрим в голоса за реф % vote, err := c.Single("SELECT user_id FROM votes_referral WHERE user_id = ?", c.SessUserId).Int64() if err != nil { return "", utils.ErrInfo(err) } last_tx, err = c.GetLastTx(c.SessUserId, utils.TypesToIds([]string{"VotesComplex"}), 1, c.TimeFormat) if (len(last_tx) > 0 && (len(last_tx[0]["queue_tx"]) > 0 || len(last_tx[0]["tx"]) > 0)) || vote > 0 { progressBar["vote"] = 1 } if c.SessRestricted == 0 { // выполнялись ли задания myTasks, err := c.Single("SELECT id FROM " + c.MyPrefix + "my_tasks").Int64() if err != nil { return "", utils.ErrInfo(err) } if myTasks > 0 { progressBar["tasks"] = 1 } } // сколько майнеров зарегались по ключам данного юзера progressBar["referral"], err = c.Single(` SELECT count(miner_id) FROM users LEFT JOIN miners_data on miners_data.user_id = users.user_id WHERE referral = ? AND miner_id > 0 `, c.SessUserId).Int64() if err != nil { return "", utils.ErrInfo(err) } // итог progressPct := progressBarPct["begin"] for name, result := range progressBar { if name == "referral" { progressPct += progressBarPct[name] * result } else { progressPct += progressBarPct[name] } } progressBar["begin"] = 1 log.Debug("ProgressBar end") if !c.ContentInc { data, err := static.Asset("static/templates/progress_bar.html") if err != nil { return "", utils.ErrInfo(err) } t := template.Must(template.New("template").Parse(string(data))) b := new(bytes.Buffer) t.ExecuteTemplate(b, "progressBar", &progressBarPage{Lang: c.Lang, ProgressPct: progressPct}) return b.String(), nil } else { TemplateStr, err := makeTemplate("progress", "progress", &progressBarPage{ Lang: c.Lang, ProgressBar: progressBar, ProgressBarPct: progressBarPct, ProgressPct: progressPct}) if err != nil { return "", utils.ErrInfo(err) } return TemplateStr, nil } }