func (t *TcpServer) Type11() { /* Получаем данные от send_to_pool */ log.Debug("Type11") // размер данных buf := make([]byte, 4) _, err := t.Conn.Read(buf) if err != nil { log.Error("%v", utils.ErrInfo(err)) return } size := utils.BinToDec(buf) log.Debug("size: %d", size) if size < 32<<20 { // сами данные log.Debug("read data") binaryData := make([]byte, size) //binaryData, err = ioutil.ReadAll(t.Conn) _, err = io.ReadFull(t.Conn, binaryData) if err != nil { log.Error("%v", utils.ErrInfo(err)) return } //log.Debug("binaryData %x", binaryData) userId := utils.BinToDec(utils.BytesShift(&binaryData, 5)) log.Debug("userId %d", userId) // проверим, есть ли такой юзер на пуле inPool, err := t.Single(`SELECT user_id FROM community WHERE user_id=?`, userId).Int64() if inPool <= 0 { log.Error("%v", utils.ErrInfo("inPool<=0")) _, err = t.Conn.Write(utils.DecToBin(0, 1)) return } log.Debug("inPool %d", inPool) filesSign := utils.BytesShift(&binaryData, utils.DecodeLength(&binaryData)) log.Debug("filesSign %x", filesSign) forSign := "" var files []string for i := 0; i < 3; i++ { size := utils.DecodeLength(&binaryData) log.Debug("size %d", size) data := utils.BytesShift(&binaryData, size) //log.Debug("data %x", data) fileType := utils.BinToDec(utils.BytesShift(&data, 1)) log.Debug("fileType %d", fileType) var name string switch fileType { case 0: name = utils.Int64ToStr(userId) + "_user_face.jpg" case 1: name = utils.Int64ToStr(userId) + "_user_profile.jpg" case 2: name = utils.Int64ToStr(userId) + "_user_video.mp4" /*case 3: name = utils.Int64ToStr(userId)+"_user_video.webm" case 4: name = utils.Int64ToStr(userId)+"_user_video.ogv"*/ } forSign = forSign + string(utils.DSha256((data))) + "," log.Debug("forSign %s", forSign) err = ioutil.WriteFile(os.TempDir()+"/"+name, data, 0644) if err != nil { log.Error("%v", utils.ErrInfo(err)) return } files = append(files, name) log.Debug("files %d", files) if len(binaryData) == 0 { break } } if len(forSign) == 0 { log.Error("%v", utils.ErrInfo("len(forSign) == 0")) _, err = t.Conn.Write(utils.DecToBin(0, 1)) return } if len(files) == 3 { forSign = forSign[:len(forSign)-1] } // проверим подпись publicKey, err := t.GetUserPublicKey(userId) resultCheckSign, err := utils.CheckSign([][]byte{[]byte(publicKey)}, forSign, utils.HexToBin(filesSign), true) if err != nil { log.Error("%v", utils.ErrInfo(err)) _, err = t.Conn.Write(utils.DecToBin(0, 1)) return } if resultCheckSign { for i := 0; i < len(files); i++ { utils.CopyFileContents(os.TempDir()+"/"+files[i], *utils.Dir+"/public/"+files[i]) } } else { for i := 0; i < len(files); i++ { os.Remove(os.TempDir() + "/" + files[i]) } } // и возвращаем статус _, err = t.Conn.Write(utils.DecToBin(1, 1)) if err != nil { log.Error("%v", utils.ErrInfo(err)) return } } else { log.Error("%v", utils.ErrInfo("size>32mb")) } }
func (p *Parser) VotesNodeNewMiner() error { var votes [2]int64 votesData, err := p.OneRow("SELECT user_id, votes_start_time, votes_0, votes_1 FROM votes_miners WHERE id = ?", p.TxMaps.Int64["vote_id"]).Int64() if err != nil { return p.ErrInfo(err) } log.Debug("votesData", votesData) log.Debug("votesData[user_id]", votesData["user_id"]) minersData, err := p.OneRow("SELECT photo_block_id, photo_max_miner_id, miners_keepers, log_id FROM miners_data WHERE user_id = ?", votesData["user_id"]).String() log.Debug("minersData", minersData) // $votes_data['user_id'] - это юзер, за которого голосуют if err != nil { return p.ErrInfo(err) } votes[0] = votesData["votes_0"] votes[1] = votesData["votes_1"] // прибавим голос votes[p.TxMaps.Int64["result"]]++ // обновляем голоса. При откате просто вычитаем err = p.ExecSql("UPDATE votes_miners SET votes_"+utils.Int64ToStr(p.TxMaps.Int64["result"])+" = ? WHERE id = ?", votes[p.TxMaps.Int64["result"]], p.TxMaps.Int64["vote_id"]) if err != nil { return p.ErrInfo(err) } // логируем, чтобы юзер {$this->tx_data['user_id']} не смог повторно проголосовать err = p.ExecSql("INSERT INTO log_votes (user_id, voting_id, type) VALUES (?, ?, 'votes_miners')", p.TxMaps.Int64["user_id"], p.TxMaps.Int64["vote_id"]) if err != nil { return p.ErrInfo(err) } // ID майнеров, у которых сохраняются фотки minersIds := utils.GetMinersKeepers(minersData["photo_block_id"], minersData["photo_max_miner_id"], minersData["miners_keepers"], true) log.Debug("minersIds", minersIds, len(minersIds)) // данные для проверки окончания голосования minerData := new(MinerData) minerData.myMinersIds, err = p.getMyMinersIds() if err != nil { return p.ErrInfo(err) } minerData.adminUiserId, err = p.GetAdminUserId() if err != nil { return p.ErrInfo(err) } minerData.minersIds = minersIds minerData.votes0 = votes[0] minerData.votes1 = votes[1] minerData.minMinersKeepers = p.Variables.Int64["min_miners_keepers"] log.Debug("minerData.adminUiserId %v", minerData.adminUiserId) log.Debug("minerData.myMinersIds %v", minerData.myMinersIds) log.Debug("minerData.minersIds %v", minerData.minersIds) log.Debug("minerData.votes0 %v", minerData.votes0) log.Debug("minerData.votes1 %v", minerData.votes1) log.Debug("minerData.minMinersKeepers %v", minerData.minMinersKeepers) if p.minersCheckVotes1(minerData) || (minerData.votes0 > minerData.minMinersKeepers || int(minerData.votes0) == len(minerData.minersIds)) { // отмечаем, что голосование нодов закончено err = p.ExecSql("UPDATE votes_miners SET votes_end = 1, end_block_id = ? WHERE id = ?", p.BlockData.BlockId, p.TxMaps.Int64["vote_id"]) if err != nil { return p.ErrInfo(err) } } if p.minersCheckVotes1(minerData) || p.minersCheckMyMinerIdAndVotes0(minerData) { // отметим del_block_id всем, кто голосовал за данного юзера, // чтобы через N блоков по крону удалить бесполезные записи err = p.ExecSql("UPDATE log_votes SET del_block_id = ? WHERE voting_id = ? AND type = 'votes_miners'", p.BlockData.BlockId, p.TxMaps.Int64["vote_id"]) if err != nil { return p.ErrInfo(err) } } // если набрано >=X голосов "за", то пишем в БД, что юзер готов к проверке людьми // либо если набранное кол-во голосов= кол-ву майнеров (актуально в самом начале запуска проекта) if p.minersCheckVotes1(minerData) { err = p.ExecSql("INSERT INTO votes_miners ( user_id, type, votes_start_time ) VALUES ( ?, 'user_voting', ? )", votesData["user_id"], p.BlockData.Time) if err != nil { return p.ErrInfo(err) } // и отмечаем лицо как готовое участвовать в поиске дублей err = p.ExecSql("UPDATE faces SET status = 'used' WHERE user_id = ?", votesData["user_id"]) if err != nil { return p.ErrInfo(err) } } else if p.minersCheckMyMinerIdAndVotes0(minerData) { // если набрано >5 голосов "против" и мы среди тех X майнеров, которые копировали фото к себе // либо если набранное кол-во голосов = кол-ву майнеров (актуально в самом начале запуска проекта) facePath := fmt.Sprintf(*utils.Dir+"/public/face_%v.jpg", votesData["user_id"]) profilePath := fmt.Sprintf(*utils.Dir+"/public/profile_%v.jpg", votesData["user_id"]) faceRandName := "" profileRandName := "" // возможно фото к нам не было скопировано, т.к. хост был недоступен. if _, err := os.Stat(profilePath); os.IsNotExist(err) { faceRandName = "" profileRandName = "" } else if _, err := os.Stat(facePath); os.IsNotExist(err) { faceRandName = "" profileRandName = "" } else { faceRandName = utils.RandSeq(30) profileRandName = utils.RandSeq(30) // перемещаем фото в корзину, откуда по крону будем удалять данные err = utils.CopyFileContents(facePath, faceRandName) if err != nil { return p.ErrInfo(err) } err = os.Remove(facePath) if err != nil { return p.ErrInfo(err) } err = utils.CopyFileContents(profilePath, profileRandName) if err != nil { return p.ErrInfo(err) } err = os.Remove(profilePath) if err != nil { return p.ErrInfo(err) } // если в корзине что-то есть, то логируем // отсутствие файлов также логируем, т.к. больше негде, а при откате эти данные очень важны. logData, err := p.OneRow("SELECT * FROM recycle_bin WHERE user_id = ?", votesData["user_id"]).String() if err != nil { return p.ErrInfo(err) } if len(logData) > 0 { logId, err := p.ExecSqlGetLastInsertId("INSERT INTO log_recycle_bin ( user_id, profile_file_name, face_file_name, block_id, prev_log_id ) VALUES ( ?, ?, ?, ?, ? )", "log_id", logData["user_id"], logData["profile_file_name"], logData["face_file_name"], p.BlockData.BlockId, logData["log_id"]) if err != nil { return p.ErrInfo(err) } err = p.ExecSql("UPDATE recycle_bin SET profile_file_name = ?, face_file_name = ?, log_id = ? WHERE user_id = ?", profileRandName, faceRandName, logId, logData["user_id"]) if err != nil { return p.ErrInfo(err) } } else { err = p.ExecSql("INSERT INTO recycle_bin ( user_id, profile_file_name, face_file_name ) VALUES ( ?, ?, ? )", votesData["user_id"], profileRandName, faceRandName) if err != nil { return p.ErrInfo(err) } } } } return nil }
func Start(dir string, thrustWindowLoder *window.Window) { var err error IosLog("start") defer func() { if r := recover(); r != nil { log.Error("Recovered", r) panic(r) } }() if dir != "" { fmt.Println("dir", dir) *utils.Dir = dir } IosLog("dir:" + dir) fmt.Println("utils.Dir", *utils.Dir) fmt.Println("dcVersion:", consts.VERSION) log.Debug("dcVersion: %v", consts.VERSION) // читаем config.ini configIni := make(map[string]string) configIni_, err := config.NewConfig("ini", *utils.Dir+"/config.ini") if err != nil { IosLog("err:" + fmt.Sprintf("%s", utils.ErrInfo(err))) log.Error("%v", utils.ErrInfo(err)) } else { configIni, err = configIni_.GetSection("default") } // убьем ранее запущенный Dcoin if !utils.Mobile() { fmt.Println("kill dcoin.pid") if _, err := os.Stat(*utils.Dir + "/dcoin.pid"); err == nil { dat, err := ioutil.ReadFile(*utils.Dir + "/dcoin.pid") if err != nil { log.Error("%v", utils.ErrInfo(err)) } var pidMap map[string]string err = json.Unmarshal(dat, &pidMap) if err != nil { log.Error("%v", utils.ErrInfo(err)) } fmt.Println("old PID ("+*utils.Dir+"/dcoin.pid"+"):", pidMap["pid"]) utils.DB, err = utils.NewDbConnect(configIni) err = KillPid(pidMap["pid"]) if nil != err { fmt.Println(err) log.Error("KillPid %v", utils.ErrInfo(err)) } if fmt.Sprintf("%s", err) != "null" { fmt.Println(fmt.Sprintf("%s", err)) // даем 15 сек, чтобы завершиться предыдущему процессу for i := 0; i < 15; i++ { log.Debug("waiting killer %d", i) if _, err := os.Stat(*utils.Dir + "/dcoin.pid"); err == nil { fmt.Println("waiting killer") utils.Sleep(1) } else { // если dcoin.pid нет, значит завершился break } } } } } // сохраним текущий pid и версию if !utils.Mobile() { pid := os.Getpid() PidAndVer, err := json.Marshal(map[string]string{"pid": utils.IntToStr(pid), "version": consts.VERSION}) if err != nil { log.Error("%v", utils.ErrInfo(err)) } err = ioutil.WriteFile(*utils.Dir+"/dcoin.pid", PidAndVer, 0644) if err != nil { log.Error("%v", utils.ErrInfo(err)) panic(err) } } controllers.SessInit() controllers.ConfigInit() daemons.ConfigInit() go func() { utils.DB, err = utils.NewDbConnect(configIni) log.Debug("%v", utils.DB) IosLog("utils.DB:" + fmt.Sprintf("%v", utils.DB)) if err != nil { IosLog("err:" + fmt.Sprintf("%s", utils.ErrInfo(err))) log.Error("%v", utils.ErrInfo(err)) panic(err) os.Exit(1) } }() f, err := os.OpenFile(*utils.Dir+"/dclog.txt", os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0777) if err != nil { IosLog("err:" + fmt.Sprintf("%s", utils.ErrInfo(err))) log.Error("%v", utils.ErrInfo(err)) panic(err) os.Exit(1) } defer f.Close() IosLog("configIni:" + fmt.Sprintf("%v", configIni)) var backend *logging.LogBackend switch configIni["log_output"] { case "file": backend = logging.NewLogBackend(f, "", 0) case "console": backend = logging.NewLogBackend(os.Stderr, "", 0) case "file_console": //backend = logging.NewLogBackend(io.MultiWriter(f, os.Stderr), "", 0) default: backend = logging.NewLogBackend(f, "", 0) } backendFormatter := logging.NewBackendFormatter(backend, format) backendLeveled := logging.AddModuleLevel(backendFormatter) logLevel_ := "DEBUG" if *utils.LogLevel == "" { logLevel_ = configIni["log_level"] } else { logLevel_ = *utils.LogLevel } logLevel, err := logging.LogLevel(logLevel_) if err != nil { log.Error("%v", utils.ErrInfo(err)) } log.Debug("logLevel: %v", logLevel) backendLeveled.SetLevel(logLevel, "") logging.SetBackend(backendLeveled) rand.Seed(time.Now().UTC().UnixNano()) // если есть OldFileName, значит работаем под именем tmp_dc и нужно перезапуститься под нормальным именем log.Error("OldFileName %v", *utils.OldFileName) if *utils.OldFileName != "" { // вначале нужно обновить БД в зависимости от версии dat, err := ioutil.ReadFile(*utils.Dir + "/dcoin.pid") if err != nil { log.Error("%v", utils.ErrInfo(err)) } var pidMap map[string]string err = json.Unmarshal(dat, &pidMap) if err != nil { log.Error("%v", utils.ErrInfo(err)) } log.Debug("OldFileName %v", *utils.OldFileName) err = utils.CopyFileContents(*utils.Dir+`/dc.tmp`, *utils.OldFileName) if err != nil { log.Debug("%v", os.Stderr) log.Debug("%v", utils.ErrInfo(err)) } // ждем подключения к БД for { if utils.DB == nil || utils.DB.DB == nil { utils.Sleep(1) continue } break } if len(pidMap["version"]) > 0 { if utils.VersionOrdinal(pidMap["version"]) < utils.VersionOrdinal("1.0.2b5") { log.Debug("%v", "ALTER TABLE config ADD COLUMN analytics_disabled smallint") err = utils.DB.ExecSql(`ALTER TABLE config ADD COLUMN analytics_disabled smallint`) if err != nil { log.Error("%v", utils.ErrInfo(err)) } } if utils.VersionOrdinal(pidMap["version"]) < utils.VersionOrdinal("2.0.1b2") { log.Debug("%v", "ALTER TABLE config ADD COLUMN sqlite_db_url varchar(255)") err = utils.DB.ExecSql(`ALTER TABLE config ADD COLUMN sqlite_db_url varchar(255)`) if err != nil { log.Error("%v", utils.ErrInfo(err)) } } } err = utils.DB.Close() if err != nil { log.Error("%v", utils.ErrInfo(err)) } fmt.Println("DB Closed") err = os.Remove(*utils.Dir + "/dcoin.pid") if err != nil { log.Error("%v", utils.ErrInfo(err)) } log.Debug("dc.tmp %v", *utils.Dir+`/dc.tmp`) err = exec.Command(*utils.OldFileName, "-dir", *utils.Dir).Start() if err != nil { log.Debug("%v", os.Stderr) log.Debug("%v", utils.ErrInfo(err)) } log.Debug("OldFileName %v", *utils.OldFileName) os.Exit(1) } // откат БД до указанного блока if *utils.RollbackToBlockId > 0 { utils.DB, err = utils.NewDbConnect(configIni) parser := new(dcparser.Parser) parser.DCDB = utils.DB err = parser.RollbackToBlockId(*utils.RollbackToBlockId) if err != nil { fmt.Println(err) panic(err) } fmt.Print("complete") os.Exit(0) } log.Debug("public") IosLog("public") if _, err := os.Stat(*utils.Dir + "/public"); os.IsNotExist(err) { err = os.Mkdir(*utils.Dir+"/public", 0755) if err != nil { log.Error("%v", utils.ErrInfo(err)) panic(err) os.Exit(1) } } log.Debug("daemonsStart") IosLog("daemonsStart") daemons.StartDaemons() IosLog("MonitorDaemons") // мониторинг демонов daemonsTable := make(map[string]string) go func() { for { daemonNameAndTime := <-daemons.MonitorDaemonCh daemonsTable[daemonNameAndTime[0]] = daemonNameAndTime[1] if utils.Time()%10 == 0 { log.Debug("daemonsTable: %v\n", daemonsTable) } } }() // сигналы демонам для выхода IosLog("signals") stopdaemons.Signals() utils.Sleep(1) // мониторим сигнал из БД о том, что демонам надо завершаться go stopdaemons.WaitStopTime() BrowserHttpHost := "http://localhost:8089" HandleHttpHost := "" ListenHttpHost := ":" + *utils.ListenHttpHost go func() { // уже прошли процесс инсталяции, где юзер указал БД и был перезапуск кошелька if len(configIni["db_type"]) > 0 && !utils.Mobile() { for { // ждем, пока произойдет подключение к БД в другой гоурутине if utils.DB == nil || utils.DB.DB == nil { utils.Sleep(1) fmt.Println("wait DB") } else { break } } fmt.Println("GET http host") BrowserHttpHost, HandleHttpHost, ListenHttpHost = GetHttpHost() // для биржы нужен хост или каталог, поэтому нужно подключение к БД exhangeHttpListener(HandleHttpHost) // для ноды тоже нужна БД tcpListener() } IosLog(fmt.Sprintf("BrowserHttpHost: %v, HandleHttpHost: %v, ListenHttpHost: %v", BrowserHttpHost, HandleHttpHost, ListenHttpHost)) fmt.Printf("BrowserHttpHost: %v, HandleHttpHost: %v, ListenHttpHost: %v\n", BrowserHttpHost, HandleHttpHost, ListenHttpHost) // включаем листинг веб-сервером для клиентской части http.HandleFunc(HandleHttpHost+"/", controllers.Index) http.HandleFunc(HandleHttpHost+"/content", controllers.Content) http.HandleFunc(HandleHttpHost+"/ajax", controllers.Ajax) http.HandleFunc(HandleHttpHost+"/tools", controllers.Tools) http.HandleFunc(HandleHttpHost+"/cf/", controllers.IndexCf) http.HandleFunc(HandleHttpHost+"/cf/content", controllers.ContentCf) http.Handle(HandleHttpHost+"/public/", noDirListing(http.FileServer(http.Dir(*utils.Dir)))) http.Handle(HandleHttpHost+"/static/", http.FileServer(&assetfs.AssetFS{Asset: static.Asset, AssetDir: static.AssetDir, Prefix: ""})) log.Debug("ListenHttpHost", ListenHttpHost) IosLog(fmt.Sprintf("ListenHttpHost: %v", ListenHttpHost)) fmt.Println("ListenHttpHost", ListenHttpHost) httpListener(ListenHttpHost, BrowserHttpHost) if *utils.Console == 0 && !utils.Mobile() { utils.Sleep(1) if thrustWindowLoder != nil { thrustWindowLoder.Close() thrustWindow := thrust.NewWindow(thrust.WindowOptions{ RootUrl: BrowserHttpHost, Size: commands.SizeHW{Width: 1024, Height: 600}, }) thrustWindow.HandleEvent("*", func(cr commands.EventResult) { fmt.Println("HandleEvent", cr) }) thrustWindow.HandleRemote(func(er commands.EventResult, this *window.Window) { fmt.Println("RemoteMessage Recieved:", er.Message.Payload) openBrowser(er.Message.Payload) // Keep in mind once we have the message, lets say its json of some new type we made, // We can unmarshal it to that type. // Same goes for the other way around. this.SendRemoteMessage("boop") }) thrustWindow.Show() thrustWindow.Focus() } else { openBrowser(BrowserHttpHost) } } }() // ожидает появления свежих записей в чате, затем ждет появления коннектов // (заносятся из демеона connections и от тех, кто сам подключился к ноде) go utils.ChatOutput(utils.ChatNewTx) log.Debug("ALL RIGHT") IosLog("ALL RIGHT") fmt.Println("ALL RIGHT") utils.Sleep(3600 * 24 * 90) log.Debug("EXIT") }
func (p *Parser) VotesNodeNewMinerRollback() error { votesData, err := p.OneRow("SELECT user_id, votes_start_time, votes_0, votes_1 FROM votes_miners WHERE id = ?", p.TxMaps.Int64["vote_id"]).Int64() if err != nil { return p.ErrInfo(err) } minersData, err := p.OneRow("SELECT photo_block_id, photo_max_miner_id, miners_keepers, log_id FROM miners_data WHERE user_id = ?", votesData["user_id"]).String() if err != nil { return p.ErrInfo(err) } minerData := new(MinerData) // запомним голоса- пригодится чуть ниже в minersCheckVotes1 minerData.votes0 = votesData["votes_0"] minerData.votes1 = votesData["votes_1"] var votes [2]int64 votes[0] = votesData["votes_0"] votes[1] = votesData["votes_1"] // вычтем голос votes[p.TxMaps.Int64["result"]]-- // обновляем голоса err = p.ExecSql("UPDATE votes_miners SET votes_"+utils.Int64ToStr(p.TxMaps.Int64["result"])+" = ? WHERE id = ?", votes[p.TxMaps.Int64["result"]], p.TxMaps.Int64["vote_id"]) 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) } minersIds := utils.GetMinersKeepers(minersData["photo_block_id"], minersData["photo_max_miner_id"], minersData["miners_keepers"], true) minerData.myMinersIds, err = p.getMyMinersIds() if err != nil { return p.ErrInfo(err) } minerData.minersIds = minersIds minerData.minMinersKeepers = p.Variables.Int64["min_miners_keepers"] if p.minersCheckVotes1(minerData) || p.minersCheckMyMinerIdAndVotes0(minerData) { // отменяем отметку о том, что голосование нодов закончено err = p.ExecSql("UPDATE votes_miners SET votes_end = 0, end_block_id = 0 WHERE id = ?", p.TxMaps.Int64["vote_id"]) 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) } } // если набрано >=5 голосов, то отменяем в БД, что юзер готов к проверке людьми if p.minersCheckVotes1(minerData) { // отменяем созданное юзерское голосование err = p.ExecSql("DELETE FROM votes_miners WHERE user_id = ? AND votes_start_time = ? AND type = 'user_voting'", votesData["user_id"], p.BlockData.Time) if err != nil { return p.ErrInfo(err) } err = p.rollbackAI("votes_miners", 1) if err != nil { return p.ErrInfo(err) } // и отмечаем лицо как неучаствующее в поиске клонов err = p.ExecSql("UPDATE faces SET status = 'pending' WHERE user_id = ?", votesData["user_id"]) if err != nil { return p.ErrInfo(err) } } else if p.minersCheckMyMinerIdAndVotes0(minerData) { // если фото плохое и мы среди тех 10 майнеров, которые копировали (или нет) фото к себе, // а затем переместили фото в корзину // получаем rand_name из логов data, err := p.OneRow("SELECT profile_file_name, face_file_name FROM recycle_bin WHERE user_id = ?", votesData["user_id"]).String() if err != nil { return p.ErrInfo(err) } // перемещаем фото из корзины, если есть, что перемещать if len(data["profile_file_name"]) > 0 && len(data["face_file_name"]) > 0 { utils.CopyFileContents("recycle_bin/"+data["face_file_name"], *utils.Dir+"/public/face_"+utils.Int64ToStr(votesData["user_id"])+".jpg") utils.CopyFileContents("recycle_bin/"+data["profile_file_name"], *utils.Dir+"/public/profile_"+utils.Int64ToStr(votesData["user_id"])+".jpg") } p.generalRollback("recycle_bin", votesData["user_id"], "", false) } return nil }
func (t *TcpServer) Type12() { /* Получаем данные от send_promised_amount_to_pool */ log.Debug("Type12") // размер данных buf := make([]byte, 4) _, err := t.Conn.Read(buf) if err != nil { log.Error("%v", utils.ErrInfo(err)) return } size := utils.BinToDec(buf) log.Debug("size: %d", size) if size < 32<<20 { // сами данные log.Debug("read data") binaryData := make([]byte, size) _, err = io.ReadFull(t.Conn, binaryData) if err != nil { log.Error("%v", utils.ErrInfo(err)) return } //log.Debug("binaryData %x", binaryData) userId := utils.BinToDec(utils.BytesShift(&binaryData, 5)) currencyId := utils.BinToDec(utils.BytesShift(&binaryData, 1)) log.Debug("userId %d", userId) log.Debug("currencyId %d", currencyId) // проверим, есть ли такой юзер на пуле inPool, err := t.Single(`SELECT user_id FROM community WHERE user_id=?`, userId).Int64() if inPool <= 0 { log.Error("%v", utils.ErrInfo("inPool<=0")) _, err = t.Conn.Write(utils.DecToBin(0, 1)) return } log.Debug("inPool %d", inPool) filesSign := utils.BytesShift(&binaryData, utils.DecodeLength(&binaryData)) log.Debug("filesSign %x", filesSign) size := utils.DecodeLength(&binaryData) log.Debug("size %d", size) data := utils.BytesShift(&binaryData, size) //log.Debug("data %x", data) fileType := utils.BinToDec(utils.BytesShift(&data, 1)) log.Debug("fileType %d", fileType) fileName := utils.Int64ToStr(userId) + "_promised_amount_" + utils.Int64ToStr(currencyId) + ".mp4" forSign := string(utils.DSha256((data))) log.Debug("forSign %s", forSign) err = ioutil.WriteFile(os.TempDir()+"/"+fileName, data, 0644) if err != nil { log.Error("%v", utils.ErrInfo(err)) return } if len(forSign) == 0 { log.Error("%v", utils.ErrInfo("len(forSign) == 0")) _, err = t.Conn.Write(utils.DecToBin(0, 1)) return } // проверим подпись publicKey, err := t.GetUserPublicKey(userId) resultCheckSign, err := utils.CheckSign([][]byte{[]byte(publicKey)}, forSign, utils.HexToBin(filesSign), true) if err != nil { log.Error("%v", utils.ErrInfo(err)) _, err = t.Conn.Write(utils.DecToBin(0, 1)) return } if resultCheckSign { utils.CopyFileContents(os.TempDir()+"/"+fileName, *utils.Dir+"/public/"+fileName) } else { os.Remove(os.TempDir() + "/" + fileName) } // и возвращаем статус _, err = t.Conn.Write(utils.DecToBin(1, 1)) if err != nil { log.Error("%v", utils.ErrInfo(err)) return } } else { log.Error("%v", utils.ErrInfo("size>32mb")) } }