func main() { f := tests_utils.InitLog() defer f.Close() txType := "NewUser" txTime := "1427383713" userId := []byte("2") var blockId int64 = 128008 var txSlice [][]byte // hash txSlice = append(txSlice, []byte("1111111111")) // type txSlice = append(txSlice, utils.Int64ToByte(utils.TypeInt(txType))) // time txSlice = append(txSlice, []byte(txTime)) // user_id txSlice = append(txSlice, []byte("1")) // public_key txSlice = append(txSlice, utils.HexToBin([]byte("30820122300d06092a864886f70d01010105000382010f003082010a0282010100ae7797b5c16358862f083bb26cde86b233ba97c48087df44eaaf88efccfe554bf51df8dc7e99072cbe433933f1b87aa9ef62bd5d49dc40e75fe398426c727b0773ea9e4d88184d64c1aa561b1cdf78abe07ca5d23711c403f58abf30d41f4b96161649a91a95818d9d482e8fa3f91829abce3d80f6fc3708ce23f6841bb4a8bae301b23745fce5134420fec0519a081f162d16e4dd0da2e8869b5b67122a1fb7e9bcdb8b2512d1edabdb271bee190563b36a66f5498f50d2fc7202ad2f43b90f860428d5ecd67973900d9997475d4e1a1e4c56b44411cc4b5e9c660fe23fdcd5ab956a834fa05a4ecac9d815143d84993c9424d86379b6f76e3be9aeaaff48fb0203010001)"))) // sign txSlice = append(txSlice, []byte("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111")) blockData := new(utils.BlockData) blockData.BlockId = blockId blockData.Time = utils.StrToInt64(txTime) blockData.UserId = utils.BytesToInt64(userId) err := tests_utils.MakeTest(txSlice, blockData, txType, "work_and_rollback") if err != nil { fmt.Println(err) } }
func main() { f := tests_utils.InitLog() defer f.Close() txType := "ChangeNodeKey" txTime := "1427383713" userId := []byte("2") var blockId int64 = 128008 var txSlice [][]byte // hash txSlice = append(txSlice, []byte("1111111111")) // type txSlice = append(txSlice, utils.Int64ToByte(utils.TypeInt(txType))) // time txSlice = append(txSlice, []byte(txTime)) // user_id txSlice = append(txSlice, []byte("1")) // public_key txSlice = append(txSlice, utils.HexToBin([]byte("423423423"))) // sign txSlice = append(txSlice, []byte("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111")) blockData := new(utils.BlockData) blockData.BlockId = blockId blockData.Time = utils.StrToInt64(txTime) blockData.UserId = utils.BytesToInt64(userId) err := tests_utils.MakeTest(txSlice, blockData, txType, "work_and_rollback") if err != nil { fmt.Println(err) } }
func (c *Controller) EGateIk() (string, error) { c.r.ParseForm() fmt.Println(c.r.Form) var ikNames []string for name, _ := range c.r.Form { if name[:2] == "ik" && name != "ik_sign" { ikNames = append(ikNames, name) } } sort.Strings(ikNames) fmt.Println(ikNames) var ikValues []string for _, names := range ikNames { ikValues = append(ikValues, c.r.FormValue(names)) } ikValues = append(ikValues, c.EConfig["ik_s_key"]) fmt.Println(ikValues) sign := strings.Join(ikValues, ":") fmt.Println(sign) sign = base64.StdEncoding.EncodeToString(utils.HexToBin(utils.Md5(sign))) fmt.Println(sign) if sign != c.r.FormValue("ik_sign") { return "", errors.New("Incorrect signature") } currencyId := int64(0) if c.r.FormValue("ik_cur") == "USD" { currencyId = 1001 } if currencyId == 0 { return "", errors.New("Incorrect currencyId") } amount := utils.StrToFloat64(c.r.FormValue("ik_am")) pmId := utils.StrToInt64(c.r.FormValue("ik_inv_id")) // проверим, не зачисляли ли мы уже это платеж existsId, err := c.Single(`SELECT id FROM e_adding_funds_ik WHERE id = ?`, pmId).Int64() if err != nil { return "", utils.ErrInfo(err) } if existsId != 0 { return "", errors.New("Incorrect ik_inv_id") } paymentInfo := c.r.FormValue("ik_desc") txTime := utils.Time() err = EPayment(paymentInfo, currencyId, txTime, amount, pmId, "ik", c.ECommission) if err != nil { return "", utils.ErrInfo(err) } return ``, nil }
func TestDisseminator(t *testing.T) { defer func() { if r := recover(); r != nil { log.Error("daemon Recovered", r) panic(r) } }() dir, err := filepath.Abs(filepath.Dir(os.Args[0])) if err != nil { t.Error(err) } fmt.Println(dir) /*configIni_, err := config.NewConfig("ini", "/home/z/IdeaProjects/src/github.com/c-darwin/dcoin-go/config.ini") if err != nil { t.Error("%v", utils.ErrInfo(err)) } configIni, err := configIni_.GetSection("default") if err != nil { t.Error("%v", utils.ErrInfo(err)) }*/ host := "pool.dcoin.club:8088" userId := int64(2) myUserId := int64(4) nodePublicKey := utils.HexToBin([]byte("30820122300d06092a864886f70d01010105000382010f003082010a0282010100b85bf8eb06d70e9f28961725ec04957d9c42db127bb788623b5063b7152bdf0df9f1af08a3cdb89f354fe86c43f9f071614b75ccee04ee9e61c749f1800870ad0ada6fc9dbcb928b2049376a06ac6754f6d2832a865e2e4bcfbd1451deb6d2c1ce6a0000701bdce2ec5c20da33ea427a58e9d9bd2807e0c712676593231410b6b0a35b392693cd62e33378987db36b4549ef5f65b172afd7cca9daed6d23e5239d966de9f31a83df4b59cb67ac5c1a816ee633cfcd3a87897b6a9053f3bd4131a403e4a20f301eea5efd31803cdf468663a605cdea96cf6b1cb698b7bb38ab5feb93b68972589d22b910520aab3b20575f2d0bc28b4960b8f912f5b15cede0af0203010001")) tx := utils.HexToBin([]byte("0c55b20550013401320131013204302e3031013001300130013001300130013001300130013082010096a9486eb64fd6ca5992e96e879e60881941d7c7bc62a0b86d60d5662b3023e1b8206105cd605791019d01ebc4c0b843284ab58efb772a159066f5a635b94c4344f09f640f244d8f68264cc1c9f83b2471547504041f8c16d8e2af77b07c5fa3799c40f267b1c7fc03326195737b3c605481e4ff37713931c28bc258a83963abf3222c287346b6ba872163b63a676ba9538f6d73fac5ee90500068541c07abddc77dff14eb3a18e47b4157228fe435c79cfa2a6189cef97fcc5f9fd58d1efa4c12f3de3db2f1993d4cd029cd3471f8a82341f75df61af247b70661ae8848afc18d28ab7654f67591f271d826f3925a4b7798653651f1e8c62854ef0bf97127f182010382010056ab8e00429fd794d2b0b64dce4cb0e36d34e59090379249990bcdc824251f907fca3e912a2e1e759dd5622b42aa86149740d72faf9743262875470b57c8c6a8333358a043ec9d8033f799578547bb04eb0f09c8e51898990f4f6760af5213ff61a95506f8b294b0ded892cfa9fcdb801887d1bb405f99ce3656818ce23de0a675cf190a5b616bea7c301f1a76e3dbbfb2c576580daf49e8f83e2286f0a62e869e49295f8bb07da0c25ac0b0a1fd3e7a82887c34f7fdda2112f334e19d7c68a130447536543752ef5a51c16ae456eaf0aadc28dbabcc27e13b7c50942704258e018f6cb898fc4a3c8a7018ee9e529b5f789973b941de7336ce7bf08b79cfeae7")) hash := utils.HexToBin(utils.Md5(tx)) toBeSent := utils.DecToBin(myUserId, 5) toBeSent = append(toBeSent, utils.DecToBin(1, 1)...) toBeSent = append(toBeSent, utils.DecToBin(utils.StrToInt64("0"), 1)...) toBeSent = append(toBeSent, []byte(hash)...) fmt.Printf("hash %x %v", hash, hash) dataType := int64(1) db := DbConnect(chBreaker, chAnswer, GoroutineName) DisseminatorType1(host, userId, string(nodePublicKey), db, toBeSent, dataType) }
func (c *Controller) AlertFromAdmin() (string, error) { if c.SessRestricted != 0 { return "", utils.ErrInfo(errors.New("Permission denied")) } alertMessage := "" alert, err := utils.GetHttpTextAnswer("http://dcoin.club/alert.json") if len(alert) > 0 { alertData := new(alertType) err = json.Unmarshal([]byte(alert), &alertData) if err != nil { log.Error("%v", utils.ErrInfo(err)) } messageJson, err := json.Marshal(alertData.Message) if err != nil { log.Error("%v", utils.ErrInfo(err)) } pub, err := utils.BinToRsaPubKey(utils.HexToBin(consts.ALERT_KEY)) if err != nil { log.Error("%v", utils.ErrInfo(err)) } err = rsa.VerifyPKCS1v15(pub, crypto.SHA1, utils.HashSha1(string(messageJson)), []byte(utils.HexToBin(alertData.Signature))) if err != nil { log.Error("%v", utils.ErrInfo(err)) } if version.Compare(alertData.Message["version"], consts.VERSION, ">") { alertMessage = alertData.Message[utils.Int64ToStr(c.LangInt)] return utils.JsonAnswer(alertMessage, "success").String(), nil } } return ``, nil }
func ElectionsAdmin(chBreaker chan bool, chAnswer chan string) { defer func() { if r := recover(); r != nil { log.Error("daemon Recovered", r) panic(r) } }() const GoroutineName = "ElectionsAdmin" d := new(daemon) d.DCDB = DbConnect(chBreaker, chAnswer, GoroutineName) if d.DCDB == nil { return } d.goRoutineName = GoroutineName d.chAnswer = chAnswer d.chBreaker = chBreaker if utils.Mobile() { d.sleepTime = 3600 } else { d.sleepTime = 60 } if !d.CheckInstall(chBreaker, chAnswer, GoroutineName) { return } d.DCDB = DbConnect(chBreaker, chAnswer, GoroutineName) if d.DCDB == nil { return } err = d.notMinerSetSleepTime(1800) if err != nil { log.Error("%v", err) return } BEGIN: for { log.Info(GoroutineName) MonitorDaemonCh <- []string{GoroutineName, utils.Int64ToStr(utils.Time())} // проверим, не нужно ли нам выйти из цикла if CheckDaemonsRestart(chBreaker, chAnswer, GoroutineName) { break BEGIN } err, restart := d.dbLock() if restart { break BEGIN } if err != nil { if d.dPrintSleep(err, d.sleepTime) { break BEGIN } continue BEGIN } blockId, err := d.GetBlockId() if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } if blockId == 0 { if d.unlockPrintSleep(utils.ErrInfo("blockId == 0"), d.sleepTime) { break BEGIN } continue BEGIN } _, _, myMinerId, _, _, _, err := d.TestBlock() if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } // а майнер ли я ? if myMinerId == 0 { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } variables, err := d.GetAllVariables() curTime := utils.Time() // проверим, прошло ли 2 недели с момента последнего обновления adminTime, err := d.Single("SELECT time FROM admin").Int64() if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } if curTime-adminTime <= variables.Int64["new_pct_period"] { if d.unlockPrintSleep(utils.ErrInfo("14 day error"), d.sleepTime) { break BEGIN } continue BEGIN } // сколько всего майнеров countMiners, err := d.Single("SELECT count(miner_id) FROM miners WHERE active = 1").Int64() if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } if countMiners < 1000 { if d.unlockPrintSleep(utils.ErrInfo("countMiners < 1000"), d.sleepTime) { break BEGIN } continue BEGIN } // берем все голоса var newAdmin int64 votes_admin, err := d.GetMap(` SELECT admin_user_id, count(user_id) as votes FROM votes_admin WHERE time > ? GROUP BY admin_user_id `, "admin_user_id", "votes", curTime-variables.Int64["new_pct_period"]) if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } for admin_user_id, votes := range votes_admin { // если более 50% майнеров проголосовали if utils.StrToInt64(votes) > countMiners/2 { newAdmin = utils.StrToInt64(admin_user_id) } } if newAdmin == 0 { if d.unlockPrintSleep(utils.ErrInfo("newAdmin == 0"), d.sleepTime) { break BEGIN } continue BEGIN } _, myUserId, _, _, _, _, err := d.TestBlock() forSign := fmt.Sprintf("%v,%v,%v,%v", utils.TypeInt("NewAdmin"), curTime, myUserId, newAdmin) 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("NewAdmin"), 1) data = append(data, utils.DecToBin(curTime, 4)...) data = append(data, utils.EncodeLengthPlusData(utils.Int64ToByte(myUserId))...) data = append(data, utils.EncodeLengthPlusData(utils.Int64ToByte(newAdmin))...) 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 } p := new(dcparser.Parser) p.DCDB = d.DCDB err = p.TxParser(utils.HexToBin(utils.Md5(data)), data, true) if err != nil { if d.unlockPrintSleep(err, d.sleepTime) { break BEGIN } continue BEGIN } d.dbUnlock() if d.dSleep(d.sleepTime) { break BEGIN } } log.Debug("break BEGIN %v", GoroutineName) }
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 (c *Controller) SaveDecryptComment() (string, error) { if c.SessRestricted != 0 { return "", utils.ErrInfo(errors.New("Permission denied")) } c.r.ParseForm() commentType := c.r.FormValue("type") id := utils.StrToInt64(c.r.FormValue("id")) comment := c.r.FormValue("comment") if !utils.InSliceString(commentType, []string{"chat", "dc_transactions", "arbitrator", "seller", "cash_requests", "comments"}) { return "", utils.ErrInfo(errors.New("incorrect type")) } // == если мы майнер и это dc_transactions, то сюда прислан зашифрованный коммент, который можно расшифровать только нод-кдючем minerId, err := c.GetMinerId(c.SessUserId) if err != nil { return "", utils.ErrInfo(err) } if minerId > 0 && utils.InSliceString(commentType, []string{"dc_transactions", "arbitrator", "seller"}) { nodePrivateKey, err := c.GetNodePrivateKey(c.MyPrefix) // расшифруем коммент rsaPrivateKey, err := utils.MakePrivateKey(nodePrivateKey) if err != nil { return "", utils.ErrInfo(err) } comment_, err := rsa.DecryptPKCS1v15(rand.Reader, rsaPrivateKey, utils.HexToBin([]byte(comment))) if err != nil { return "", utils.ErrInfo(err) } comment = string(comment_) } comment = template.HTMLEscapeString(comment) if len(comment) > 0 { if utils.InSliceString(commentType, []string{"arbitrator", "seller"}) { err = c.ExecSql(` UPDATE `+c.MyPrefix+`my_comments SET comment = ?, comment_status = ? WHERE id = ? AND type = ?`, comment, "decrypted", id, commentType) if err != nil { return "", utils.ErrInfo(err) } } else if commentType == "chat" { err = c.ExecSql(` UPDATE chat SET enc_message = message, message = ?, status = ? WHERE id = ? AND receiver = ?`, comment, 2, id, c.SessUserId) if err != nil { return "", utils.ErrInfo(err) } } else { err = c.ExecSql(` UPDATE `+c.MyPrefix+`my_`+commentType+` SET comment = ?, comment_status = 'decrypted' WHERE id = ?`, comment, id) if err != nil { return "", utils.ErrInfo(err) } } } else { comment = "NULL" } return comment, nil }
/* * Каждые 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(¤cy_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) }
func (t *TcpServer) Type1() { log.Debug("dataType: 1") // размер данных buf := make([]byte, 4) n, err := t.Conn.Read(buf) if err != nil { log.Error("%v", utils.ErrInfo(err)) return } size := utils.BinToDec(buf) log.Debug("size: %v / n: %v", size, n) if size < 10485760 { // сами данные binaryData := make([]byte, size) log.Debug("ReadAll 0") _, err = io.ReadFull(t.Conn, binaryData) log.Debug("ReadAll 1") if err != nil { log.Error("%v", utils.ErrInfo(err)) return } log.Debug("binaryData: %x", binaryData) /* * принимаем зашифрованный список тр-ий от демона disseminator, которые есть у отправителя * Блоки не качаем тут, т.к. может быть цепочка блоков, а их качать долго * тр-ии качаем тут, т.к. они мелкие и точно скачаются за 60 сек * */ key, iv, decryptedBinData, err := t.DecryptData(&binaryData) if err != nil { log.Error("%v", utils.ErrInfo(err)) return } log.Debug("key: %v / iv: %v", key, iv) /* * структура данных: * user_id - 5 байт * type - 1 байт. 0 - блок, 1 - список тр-ий * {если type==1}: * <любое кол-во следующих наборов> * high_rate - 1 байт * tx_hash - 16 байт * </> * {если type==0}: * block_id - 3 байта * hash - 32 байт * head_hash - 32 байт * <любое кол-во следующих наборов> * high_rate - 1 байт * tx_hash - 16 байт * </> * */ blockId, err := t.GetBlockId() if err != nil { log.Error("%v", utils.ErrInfo(err)) return } log.Debug("decryptedBinData: %x", decryptedBinData) // user_id отправителя, чтобы знать у кого брать данные, когда они будут скачиваться другим скриптом newDataUserId := utils.BinToDec(utils.BytesShift(&decryptedBinData, 5)) log.Debug("newDataUserId: %d", newDataUserId) // данные могут быть отправлены юзером, который уже не майнер minerId, err := t.Single("SELECT miner_id FROM miners_data WHERE user_id = ? AND miner_id > 0", newDataUserId).Int64() if err != nil { log.Error("%v", utils.ErrInfo(err)) return } log.Debug("minerId: %v", minerId) if minerId == 0 { log.Error("%v", utils.ErrInfo(err)) return } // если 0 - значит вначале идет инфа о блоке, если 1 - значит сразу идет набор хэшей тр-ий newDataType := utils.BinToDecBytesShift(&decryptedBinData, 1) log.Debug("newDataType: %d", newDataType) if newDataType == 0 { // ID блока, чтобы не скачать старый блок newDataBlockId := utils.BinToDecBytesShift(&decryptedBinData, 3) log.Debug("newDataBlockId: %d / blockId: %d", newDataBlockId, blockId) // нет смысла принимать старые блоки if newDataBlockId >= blockId { // Это хэш для соревнования, у кого меньше хэш newDataHash := utils.BinToHex(utils.BytesShift(&decryptedBinData, 32)) // Для доп. соревнования, если head_hash равны (шалит кто-то из майнеров и позже будет за такое забанен) newDataHeadHash := utils.BinToHex(utils.BytesShift(&decryptedBinData, 32)) err = t.ExecSql(`DELETE FROM queue_blocks WHERE hex(hash) = ?`, newDataHash) if err != nil { log.Error("%v", utils.ErrInfo(err)) return } err = t.ExecSql(` INSERT INTO queue_blocks ( hash, head_hash, user_id, block_id ) VALUES ( [hex], [hex], ?, ? )`, newDataHash, newDataHeadHash, newDataUserId, newDataBlockId) if err != nil { log.Error("%v", utils.ErrInfo(err)) return } } } log.Debug("decryptedBinData: %x", decryptedBinData) var needTx []byte // Разбираем список транзакций if len(decryptedBinData) == 0 { log.Debug("%v", utils.ErrInfo("len(decryptedBinData) == 0")) return } for { // 1 - это админские тр-ии, 0 - обычные newDataHighRate := utils.BinToDecBytesShift(&decryptedBinData, 1) if len(decryptedBinData) < 16 { log.Debug("%v", utils.ErrInfo("len(decryptedBinData) < 16")) return } log.Debug("newDataHighRate: %v", newDataHighRate) newDataTxHash := utils.BinToHex(utils.BytesShift(&decryptedBinData, 16)) if len(newDataTxHash) == 0 { log.Error("%v", utils.ErrInfo(err)) return } log.Debug("newDataTxHash %s", newDataTxHash) // проверим, нет ли у нас такой тр-ии exists, err := t.Single("SELECT count(hash) FROM log_transactions WHERE hex(hash) = ?", newDataTxHash).Int64() if err != nil { log.Error("%v", utils.ErrInfo(err)) return } if exists > 0 { log.Debug("exists") continue } needTx = append(needTx, utils.HexToBin(newDataTxHash)...) if len(decryptedBinData) == 0 { break } } if len(needTx) == 0 { log.Error("%v", utils.ErrInfo(err)) return } log.Debug("needTx: %v", needTx) // шифруем данные. ключ $key сеансовый, iv тоже encData, _, err := utils.EncryptCFB(needTx, key, iv) if err != nil { log.Error("%v", utils.ErrInfo(err)) return } // в 4-х байтах пишем размер данных, которые пошлем далее size := utils.DecToBin(len(encData), 4) _, err = t.Conn.Write(size) if err != nil { log.Error("%v", utils.ErrInfo(err)) return } log.Debug("size: %v", len(encData)) log.Debug("encData: %x", encData) // далее шлем сами данные _, err = t.Conn.Write(encData) if err != nil { log.Error("%v", utils.ErrInfo(err)) return } // в ответ получаем размер данных, которые нам хочет передать сервер buf := make([]byte, 4) _, err = t.Conn.Read(buf) if err != nil { log.Error("%v", utils.ErrInfo(err)) return } dataSize := utils.BinToDec(buf) log.Debug("dataSize %v", dataSize) // и если данных менее 10мб, то получаем их if dataSize < 10485760 { encBinaryTxs := make([]byte, dataSize) _, err = io.ReadFull(t.Conn, encBinaryTxs) if err != nil { log.Error("%v", utils.ErrInfo(err)) return } // разбираем полученные данные log.Debug("encBinaryTxs %x", encBinaryTxs) // уберем IV из начала utils.BytesShift(&encBinaryTxs, 16) // декриптуем binaryTxs, err := utils.DecryptCFB(iv, encBinaryTxs, key) if err != nil { log.Error("%v", utils.ErrInfo(err)) return } log.Debug("binaryTxs %x", binaryTxs) for { txSize := utils.DecodeLength(&binaryTxs) if int64(len(binaryTxs)) < txSize { log.Error("%v", utils.ErrInfo(err)) return } txBinData := utils.BytesShift(&binaryTxs, txSize) if len(txBinData) == 0 { log.Error("%v", utils.ErrInfo(err)) return } txHex := utils.BinToHex(txBinData) // проверим размер if int64(len(txBinData)) > t.variables.Int64["max_tx_size"] { log.Debug("%v", utils.ErrInfo("len(txBinData) > max_tx_size")) return } newDataHighRate := 0 // временно для тестов log.Debug("INSERT INTO queue_tx (hash, high_rate, data) %s, %d, %s", utils.Md5(txBinData), newDataHighRate, txHex) err = t.ExecSql(`INSERT INTO queue_tx (hash, high_rate, data) VALUES ([hex], ?, [hex])`, utils.Md5(txBinData), newDataHighRate, txHex) if len(txBinData) == 0 { log.Error("%v", utils.ErrInfo(err)) return } } } } }
func (c *Controller) ECheckSign() (string, error) { c.w.Header().Set("Access-Control-Allow-Origin", "*") c.r.ParseForm() userId := utils.StrToInt64(c.r.FormValue("user_id")) sign := []byte(c.r.FormValue("sign")) if !utils.CheckInputData(string(sign), "hex_sign") { return `{"result":"incorrect sign"}`, nil } if !utils.CheckInputData(userId, "int") { return `{"result":"incorrect user_id"}`, nil } var publicKey []byte if userId == 0 { n := []byte(c.r.FormValue("n")) e := []byte(c.r.FormValue("e")) if !utils.CheckInputData(n, "hex") { return `{"result":"incorrect n"}`, nil } if !utils.CheckInputData(e, "hex") { return `{"result":"incorrect e"}`, nil } log.Debug("n %v / e %v", n, e) publicKey = utils.MakeAsn1(n, e) log.Debug("publicKey %s", publicKey) } RemoteAddr := utils.RemoteAddrFix(c.r.RemoteAddr) re := regexp.MustCompile(`(.*?):[0-9]+$`) match := re.FindStringSubmatch(RemoteAddr) if len(match) != 0 { RemoteAddr = match[1] } log.Debug("RemoteAddr %s", RemoteAddr) hash := utils.Md5(c.r.Header.Get("User-Agent") + RemoteAddr) log.Debug("hash %s", hash) forSign, err := c.Single(`SELECT data FROM e_authorization WHERE hex(hash) = ?`, hash).String() if err != nil { return "{\"result\":0}", err } if userId > 0 { publicKey_, err := c.GetUserPublicKey(userId) publicKey = []byte(publicKey_) if err != nil { return "{\"result\":0}", err } if len(publicKey_) == 0 { return "{\"result\":0}", utils.ErrInfo("len(publicKey_) == 0") } } else { userId_, err := c.GetUserIdByPublicKey(publicKey) userId = utils.StrToInt64(userId_) publicKey = utils.HexToBin(publicKey) log.Debug("userId %d", userId) if err != nil { return "{\"result\":0}", err } if userId == 0 { return "{\"result\":0}", utils.ErrInfo("userId == 0") } } log.Debug("userId %v", userId) log.Debug("publicKey %x", publicKey) log.Debug("forSign %v", forSign) log.Debug("sign %s", sign) // проверим подпись resultCheckSign, err := utils.CheckSign([][]byte{[]byte(publicKey)}, forSign, utils.HexToBin(sign), true) if err != nil { return "{\"result\":0}", err } log.Debug("resultCheckSign %v", resultCheckSign) if resultCheckSign { // если это первый запрос, то создаем запись в табле users eUserId, err := c.Single(`SELECT id FROM e_users WHERE user_id = ?`, userId).Int64() if err != nil { return "{\"result\":0}", err } if eUserId == 0 { eUserId, err = c.ExecSqlGetLastInsertId(`INSERT INTO e_users (user_id) VALUES (?)`, "id", userId) if err != nil { return "{\"result\":0}", err } } if len(c.r.FormValue("user_id")) > 0 { token := utils.RandSeq(30) err = c.ExecSql(`INSERT INTO e_tokens (token, user_id) VALUES (?, ?)`, token, eUserId) if err != nil { return "{\"result\":0}", err } log.Debug(`{"result":"1", "token":"` + token + `"}`) return `{"result":"1", "token":"` + token + `"}`, nil } else { c.sess.Set("e_user_id", eUserId) return `{"result":1}`, nil } } else { return "{\"result\":0}", nil } }
func Exchange(chBreaker chan bool, chAnswer chan string) { defer func() { if r := recover(); r != nil { log.Error("daemon Recovered", r) panic(r) } }() const GoroutineName = "Exchange" 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 } BEGIN: for { log.Info(GoroutineName) MonitorDaemonCh <- []string{GoroutineName, utils.Int64ToStr(utils.Time())} // проверим, не нужно ли нам выйти из цикла if CheckDaemonsRestart(chBreaker, chAnswer, GoroutineName) { break BEGIN } blockId, err := d.GetConfirmedBlockId() if err != nil { if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } var myPrefix string community, err := d.GetCommunityUsers() if len(community) > 0 { adminUserId, err := d.GetPoolAdminUserId() if err != nil { if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } myPrefix = utils.Int64ToStr(adminUserId) + "_" } else { myPrefix = "" } eConfig, err := d.GetMap(`SELECT * FROM e_config`, "name", "value") if err != nil { if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } confirmations := utils.StrToInt64(eConfig["confirmations"]) mainDcAccount := utils.StrToInt64(eConfig["main_dc_account"]) // все валюты, с которыми работаем currencyList, err := utils.EGetCurrencyList() if err != nil { if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } // ++++++++++++ reduction ++++++++++++ // максимальный номер блока для процентов. Чтобы брать только новые maxReductionBlock, err := d.Single(`SELECT max(block_id) FROM e_reduction`).Int64() if err != nil { if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } // если есть свежая reduction, то нужно остановить торги reduction, err := d.Single(`SELECT block_id FROM reduction WHERE block_id > ? and pct > 0`, maxReductionBlock).Int64() if err != nil { if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } if reduction > 0 { err = d.ExecSql(`INSERT INTO e_reduction_lock (time) VALUES (?)`, utils.Time()) if err != nil { log.Error("%v", utils.ErrInfo(err)) } } // если уже прошло 10 блоков с момента обнаружения reduction, то производим сокращение объема монет rows, err := d.Query(d.FormatQuery(`SELECT pct, currency_id, time, block_id FROM reduction WHERE block_id > ? AND block_id < ?`), maxReductionBlock, blockId-confirmations) if err != nil { if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } for rows.Next() { var pct float64 var currencyId, rTime, blockId int64 err = rows.Scan(&pct, ¤cyId, &rTime, &blockId) if err != nil { rows.Close() if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } // $k = (100-$row['pct'])/100; k := (100 - pct) / 100 // уменьшаем все средства на счетах err = d.ExecSql(`UPDATE e_wallets SET amount = amount * ? WHERE currency_id = ?`, k, currencyId) // уменьшаем все средства на вывод err = d.ExecSql(`UPDATE e_withdraw SET amount = amount * ? WHERE currency_id = ? AND close_time = 0`, k, currencyId) // уменьшаем все ордеры на продажу err = d.ExecSql(`UPDATE e_orders SET amount = amount * ?, begin_amount = begin_amount * ? WHERE sell_currency_id = ?`, k, k, currencyId) err = d.ExecSql(`INSERT INTO e_reduction ( time, block_id, currency_id, pct ) VALUES ( ?, ?, ?, ? )`, rTime, blockId, currencyId, pct) if err != nil { rows.Close() if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } } rows.Close() // ++++++++++++ DC ++++++++++++ /* * Важно! отключать в кроне при обнулении данных в БД * * 1. Получаем инфу о входящих переводах и начисляем их на счета юзеров * 2. Обновляем проценты * 3. Чистим кол-во отправленных смс-ок * */ nodePrivateKey, err := d.GetNodePrivateKey(myPrefix) if err != nil { if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } /* * Получаем инфу о входящих переводах и начисляем их на счета юзеров * */ // если всё остановлено из-за найденного блока с reduction, то входящие переводы не обрабатываем reductionLock, err := utils.EGetReductionLock() if err != nil { if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } if reductionLock > 0 { if d.dPrintSleep(utils.ErrInfo("reductionLock"), d.sleepTime) { break BEGIN } continue BEGIN } rows, err = d.Query(d.FormatQuery(` SELECT amount, id, block_id, type_id, currency_id, to_user_id, time, comment, comment_status FROM my_dc_transactions WHERE type = 'from_user' AND block_id < ? AND exchange_checked = 0 AND status = 'approved' AND to_user_id = ? ORDER BY id DESC`), blockId-confirmations, mainDcAccount) if err != nil { if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } for rows.Next() { var amount float64 var id, blockId, typeId, currencyId, toUserId, txTime int64 var comment, commentStatus string err = rows.Scan(&amount, &id, &blockId, &typeId, ¤cyId, &toUserId, &txTime, &comment, &commentStatus) if err != nil { rows.Close() if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } // отметим exchange_checked=1, чтобы больше не брать эту тр-ию err = d.ExecSql(`UPDATE my_dc_transactions SET exchange_checked = 1 WHERE id = ?`, id) if err != nil { rows.Close() if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } // вначале нужно проверить, точно ли есть такой перевод в блоке 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 } log.Debug("md5hash %s", txMap["md5hash"]) // если что-то случится с таблой my_dc_transactions, то все ввода на биржу будут зачислены по новой // поэтому нужно проверять e_adding_funds exists, err := d.Single(`SELECT id FROM e_adding_funds WHERE hex(tx_hash) = ?`, string(txMap["md5hash"])).Int64() if err != nil { rows.Close() if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } log.Debug("exists %d", exists) if exists != 0 { continue } log.Debug("user_id = %d / typeId = %d / currency_id = %d / currencyId = %d / amount = %f / amount = %f / comment = %s / comment = %s / to_user_id = %d / toUserId = %d ", utils.BytesToInt64(txMap["user_id"]), typeId, utils.BytesToInt64(txMap["currency_id"]), currencyId, utils.BytesToFloat64(txMap["amount"]), amount, string(utils.BinToHex(txMap["comment"])), comment, utils.BytesToInt64(txMap["to_user_id"]), toUserId) // сравнение данных из таблы my_dc_transactions с тем, что в блоке if utils.BytesToInt64(txMap["user_id"]) == typeId && utils.BytesToInt64(txMap["currency_id"]) == currencyId && utils.BytesToFloat64(txMap["amount"]) == amount && string(utils.BinToHex(txMap["comment"])) == comment && utils.BytesToInt64(txMap["to_user_id"]) == toUserId { decryptedComment := comment if commentStatus == "encrypted" { // расшифруем коммент block, _ := pem.Decode([]byte(nodePrivateKey)) 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, utils.HexToBin(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 } } // возможно юзер сделал перевод в той валюте, которая у нас на бирже еще не торгуется if len(currencyList[currencyId]) == 0 { log.Error("currencyId %d not trading", currencyId) continue } // возможно, что чуть раньше было reduction, а это значит, что все тр-ии, // которые мы ещё не обработали и которые были До блока с reduction нужно принимать с учетом reduction // т.к. средства на нашем счете уже урезались, а вот те, что после reduction - остались в том виде, в котором пришли lastReduction, err := d.OneRow("SELECT block_id, pct FROM reduction WHERE currency_id = ? ORDER BY block_id", currencyId).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) } // начисляем средства на счет того, чей id указан в комменте r, _ := regexp.Compile(`(?i)\s*#\s*([0-9]+)\s*`) user := r.FindStringSubmatch(decryptedComment) if len(user) == 0 { log.Error("len(user) == 0") continue } log.Debug("user %s", user[1]) // user_id с биржевой таблы uid := utils.StrToInt64(user[1]) userAmountAndProfit := utils.EUserAmountAndProfit(uid, currencyId) newAmount_ := userAmountAndProfit + amount utils.UpdEWallet(uid, currencyId, utils.Time(), newAmount_, true) // для отчетности запишем в историю err = d.ExecSql(` INSERT INTO e_adding_funds ( user_id, currency_id, time, amount, tx_hash ) VALUES ( ?, ?, ?, ?, ? )`, uid, currencyId, txTime, amount, string(txMap["md5hash"])) if err != nil { rows.Close() if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } } } } rows.Close() /* * Обновляем проценты * */ // максимальный номер блока для процентов. Чтобы брать только новые maxPctBlock, err := d.Single(`SELECT max(block_id) FROM e_user_pct`).Int64() log.Debug(`SELECT time, block_id, currency_id, user FROM pct WHERE block_id < ` + utils.Int64ToStr(blockId-confirmations) + ` AND block_id > ` + utils.Int64ToStr(maxPctBlock)) rows, err = d.Query(d.FormatQuery(`SELECT time, block_id, currency_id, user FROM pct WHERE block_id < ? AND block_id > ?`), blockId-confirmations, maxPctBlock) if err != nil { if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } for rows.Next() { var pct float64 var pTime, blockId, currencyId int64 err = rows.Scan(&pTime, &blockId, ¤cyId, &pct) if err != nil { rows.Close() if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } d.ExecSql(` INSERT INTO e_user_pct ( time, block_id, currency_id, pct ) VALUES ( ?, ?, ?, ? )`, pTime, blockId, currencyId, pct) } rows.Close() if d.dSleep(d.sleepTime) { break BEGIN } } log.Debug("break BEGIN %v", GoroutineName) }
/* * Каждые 2 недели собираем инфу о голосах за % и создаем тр-ию, которая * попадет в DC сеть только, если мы окажемся генератором блока * */ func PctGenerator(chBreaker chan bool, chAnswer chan string) { defer func() { if r := recover(); r != nil { log.Error("daemon Recovered", r) panic(r) } }() const GoroutineName = "PctGenerator" d := new(daemon) d.DCDB = DbConnect(chBreaker, chAnswer, GoroutineName) if d.DCDB == nil { return } d.goRoutineName = GoroutineName d.chAnswer = chAnswer d.chBreaker = chBreaker if utils.Mobile() { d.sleepTime = 3600 } else { d.sleepTime = 60 } if !d.CheckInstall(chBreaker, chAnswer, GoroutineName) { return } d.DCDB = DbConnect(chBreaker, chAnswer, GoroutineName) if d.DCDB == nil { return } err = d.notMinerSetSleepTime(1800) if err != nil { log.Error("%v", err) return } BEGIN: for { log.Info(GoroutineName) MonitorDaemonCh <- []string{GoroutineName, utils.Int64ToStr(utils.Time())} // проверим, не нужно ли нам выйти из цикла if CheckDaemonsRestart(chBreaker, chAnswer, GoroutineName) { break BEGIN } err, restart := d.dbLock() if restart { break BEGIN } if err != nil { if d.dPrintSleep(err, d.sleepTime) { break BEGIN } continue BEGIN } blockId, err := d.GetBlockId() if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } if blockId == 0 { if d.unlockPrintSleep(utils.ErrInfo("blockId == 0"), d.sleepTime) { break BEGIN } continue BEGIN } _, _, myMinerId, _, _, _, err := d.TestBlock() if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } // а майнер ли я ? if myMinerId == 0 { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } variables, err := d.GetAllVariables() curTime := utils.Time() // проверим, прошло ли 2 недели с момента последнего обновления pct pctTime, err := d.Single("SELECT max(time) FROM pct").Int64() if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } if curTime-pctTime > variables.Int64["new_pct_period"] { // берем все голоса miner_pct pctVotes := make(map[int64]map[string]map[string]int64) rows, err := d.Query("SELECT currency_id, pct, count(user_id) as votes FROM votes_miner_pct GROUP BY currency_id, pct ORDER BY currency_id, pct ASC") if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } for rows.Next() { var currency_id, votes int64 var pct string err = rows.Scan(¤cy_id, &pct, &votes) if err != nil { rows.Close() if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } log.Info("%v", "newpctcurrency_id", currency_id, "pct", pct, "votes", votes) if len(pctVotes[currency_id]) == 0 { pctVotes[currency_id] = make(map[string]map[string]int64) } if len(pctVotes[currency_id]["miner_pct"]) == 0 { pctVotes[currency_id]["miner_pct"] = make(map[string]int64) } pctVotes[currency_id]["miner_pct"][pct] = votes } rows.Close() // берем все голоса user_pct rows, err = d.Query("SELECT currency_id, pct, count(user_id) as votes FROM votes_user_pct GROUP BY currency_id, pct ORDER BY currency_id, pct ASC") if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } for rows.Next() { var currency_id, votes int64 var pct string err = rows.Scan(¤cy_id, &pct, &votes) if err != nil { rows.Close() if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } log.Info("%v", "currency_id", currency_id, "pct", pct, "votes", votes) if len(pctVotes[currency_id]) == 0 { pctVotes[currency_id] = make(map[string]map[string]int64) } if len(pctVotes[currency_id]["user_pct"]) == 0 { pctVotes[currency_id]["user_pct"] = make(map[string]int64) } pctVotes[currency_id]["user_pct"][pct] = votes } rows.Close() newPct := make(map[string]map[string]map[string]string) newPct["currency"] = make(map[string]map[string]string) var userMaxKey int64 PctArray := utils.GetPctArray() log.Info("%v", "pctVotes", pctVotes) for currencyId, data := range pctVotes { currencyIdStr := utils.Int64ToStr(currencyId) // определяем % для майнеров pctArr := utils.MakePctArray(data["miner_pct"]) log.Info("%v", "pctArrminer_pct", pctArr, currencyId) key := utils.GetMaxVote(pctArr, 0, 390, 100) log.Info("%v", "key", key) if len(newPct["currency"][currencyIdStr]) == 0 { newPct["currency"][currencyIdStr] = make(map[string]string) } newPct["currency"][currencyIdStr]["miner_pct"] = utils.GetPctValue(key) // определяем % для юзеров pctArr = utils.MakePctArray(data["user_pct"]) log.Info("%v", "pctArruser_pct", pctArr, currencyId) log.Info("%v", "newPct", newPct) pctY := utils.ArraySearch(newPct["currency"][currencyIdStr]["miner_pct"], PctArray) log.Info("%v", "newPct[currency][currencyIdStr][miner_pct]", newPct["currency"][currencyIdStr]["miner_pct"]) log.Info("%v", "PctArray", PctArray) log.Info("%v", "miner_pct $pct_y=", pctY) maxUserPctY := utils.Round(utils.StrToFloat64(pctY)/2, 2) userMaxKey = utils.FindUserPct(int(maxUserPctY)) log.Info("%v", "maxUserPctY", maxUserPctY, "userMaxKey", userMaxKey, "currencyIdStr", currencyIdStr) // отрезаем лишнее, т.к. поиск идет ровно до макимального возможного, т.е. до miner_pct/2 pctArr = utils.DelUserPct(pctArr, userMaxKey) log.Info("%v", "pctArr", pctArr) key = utils.GetMaxVote(pctArr, 0, userMaxKey, 100) log.Info("%v", "data[user_pct]", data["user_pct"]) log.Info("%v", "pctArr", pctArr) log.Info("%v", "userMaxKey", userMaxKey) log.Info("%v", "key", key) newPct["currency"][currencyIdStr]["user_pct"] = utils.GetPctValue(key) log.Info("%v", "user_pct", newPct["currency"][currencyIdStr]["user_pct"]) } newPct_ := new(newPctType) newPct_.Currency = make(map[string]map[string]string) newPct_.Currency = newPct["currency"] newPct_.Referral = make(map[string]int64) refLevels := []string{"first", "second", "third"} for i := 0; i < len(refLevels); i++ { level := refLevels[i] var votesReferral []map[int64]int64 // берем все голоса rows, err := d.Query("SELECT " + level + ", count(user_id) as votes FROM votes_referral GROUP BY " + level + " ORDER BY " + level + " ASC ") if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } for rows.Next() { var level_, votes int64 err = rows.Scan(&level_, &votes) if err != nil { rows.Close() if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } votesReferral = append(votesReferral, map[int64]int64{level_: votes}) } rows.Close() newPct_.Referral[level] = (utils.GetMaxVote(votesReferral, 0, 30, 10)) } jsonData, err := json.Marshal(newPct_) if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } _, myUserId, _, _, _, _, err := d.TestBlock() forSign := fmt.Sprintf("%v,%v,%v,%s", utils.TypeInt("NewPct"), curTime, myUserId, jsonData) log.Debug("forSign = %v", forSign) binSign, err := d.GetBinSign(forSign, myUserId) log.Debug("binSign = %x", binSign) if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } data := utils.DecToBin(utils.TypeInt("NewPct"), 1) data = append(data, utils.DecToBin(curTime, 4)...) data = append(data, utils.EncodeLengthPlusData(utils.Int64ToByte(myUserId))...) data = append(data, utils.EncodeLengthPlusData(jsonData)...) data = append(data, utils.EncodeLengthPlusData([]byte(binSign))...) err = d.InsertReplaceTxInQueue(data) if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } // и не закрывая main_lock переводим нашу тр-ию в verified=1, откатив все несовместимые тр-ии // таким образом у нас будут в блоке только актуальные голоса. // а если придет другой блок и станет verified=0, то эта тр-ия просто удалится. p := new(dcparser.Parser) p.DCDB = d.DCDB err = p.TxParser(utils.HexToBin(utils.Md5(data)), data, true) if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } } d.dbUnlock() if d.dSleep(d.sleepTime) { break BEGIN } } log.Debug("break BEGIN %v", GoroutineName) }
func (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")) } }
func (c *Controller) Check_sign() (string, error) { var checkError bool c.r.ParseForm() n := []byte(c.r.FormValue("n")) e := []byte(c.r.FormValue("e")) sign := []byte(c.r.FormValue("sign")) setupPassword := c.r.FormValue("setup_password") private_key := c.r.FormValue("private_key") if !utils.CheckInputData(n, "hex") { return `{"result":"incorrect n"}`, nil } if !utils.CheckInputData(e, "hex") { return `{"result":"incorrect e"}`, nil } if !utils.CheckInputData(string(sign), "hex_sign") { return `{"result":"incorrect sign"}`, nil } allTables, err := c.DCDB.GetAllTables() if err != nil { return "{\"result\":0}", err } var hash []byte log.Debug("configIni[sign_hash] %s", configIni["sign_hash"]) log.Debug("c.r.RemoteAddr %s", c.r.RemoteAddr) log.Debug("c.r.Header.Get(User-Agent) %s", c.r.Header.Get("User-Agent")) RemoteAddr := utils.RemoteAddrFix(c.r.RemoteAddr) re := regexp.MustCompile(`(.*?):[0-9]+$`) match := re.FindStringSubmatch(RemoteAddr) if len(match) != 0 { RemoteAddr = match[1] } log.Debug("RemoteAddr %s", RemoteAddr) hash = utils.Md5(c.r.Header.Get("User-Agent") + RemoteAddr) log.Debug("hash %s", hash) if len(c.CommunityUsers) > 0 { // в цикле проверяем, кому подойдет присланная подпись for _, userId := range c.CommunityUsers { myPrefix := utils.Int64ToStr(userId) + "_" if !utils.InSliceString(myPrefix+"my_keys", allTables) { continue } // получим открытый ключ юзера publicKey, err := c.DCDB.GetMyPublicKey(myPrefix) if err != nil { return "{\"result\":0}", err } // получим данные для подписи forSign, err := c.DCDB.GetDataAuthorization(hash) log.Debug("publicKey: %x\n", publicKey) log.Debug("myPrefix: ", myPrefix) log.Debug("sign: %s\n", sign) log.Debug("hash: %s\n", hash) log.Debug("forSign: ", forSign) // проверим подпись resultCheckSign, err := utils.CheckSign([][]byte{publicKey}, forSign, utils.HexToBin(sign), true) if err != nil { continue } // если подпись верная, значит мы нашли юзера, который эту подпись смог сделать if resultCheckSign { myUserId := userId // убираем ограниченный режим c.sess.Delete("restricted") c.sess.Set("user_id", myUserId) log.Debug("c.sess.Set(user_id) %d", myUserId) public_key, err := c.DCDB.GetUserPublicKey(myUserId) if err != nil { return "{\"result\":0}", err } // паблик кей в сессии нужен чтобы выбрасывать юзера, если ключ изменился c.sess.Set("public_key", string(utils.BinToHex([]byte(public_key)))) log.Debug("string(utils.BinToHex([]byte(public_key))) %s", string(utils.BinToHex([]byte(public_key)))) adminUSerID, err := c.DCDB.GetAdminUserId() if err != nil { return "{\"result\":0}", err } if adminUSerID == myUserId { c.sess.Set("admin", 1) } return "{\"result\":1}", nil } } log.Debug("restricted test") // если дошли досюда, значит ни один ключ не подошел и даем возможность войти в ограниченном режиме publicKey := utils.MakeAsn1(n, e) userId_, err := c.DCDB.GetUserIdByPublicKey(publicKey) userId := utils.StrToInt64(userId_) if err != nil { return "{\"result\":0}", err } log.Debug("userId:", userId) // юзер с таким ключем есть в БД if userId > 0 { // получим данные для подписи forSign, err := c.DCDB.GetDataAuthorization(hash) log.Debug("forSign", forSign) log.Debug("publicKey %x\n", utils.HexToBin(publicKey)) log.Debug("sign_", string(sign)) // проверим подпись resultCheckSign, err := utils.CheckSign([][]byte{utils.HexToBin(publicKey)}, forSign, utils.HexToBin(sign), true) if err != nil { return "{\"result\":0}", err } if resultCheckSign { // если юзер смог подписать наш хэш, значит у него актуальный праймари ключ c.sess.Set("user_id", userId) log.Debug("c.sess.Set(user_id) %d", userId) // паблик кей в сессии нужен чтобы выбрасывать юзера, если ключ изменился c.sess.Set("public_key", string(publicKey)) // возможно в табле my_keys старые данные, но если эта табла есть, то нужно добавить туда ключ if utils.InSliceString(utils.Int64ToStr(userId)+"_my_keys", allTables) { curBlockId, err := c.DCDB.GetBlockId() if err != nil { return "{\"result\":0}", err } err = c.DCDB.InsertIntoMyKey(utils.Int64ToStr(userId)+"_", publicKey, utils.Int64ToStr(curBlockId)) if err != nil { return "{\"result\":0}", err } c.sess.Delete("restricted") } else { c.sess.Set("restricted", int64(1)) log.Debug("c.sess.Set(restricted) 1") } return "{\"result\":1}", nil } else { return "{\"result\":0}", nil } } } else { // получим открытый ключ юзера publicKey, err := c.DCDB.GetMyPublicKey("") if err != nil { return "{\"result\":0}", err } // Если ключ еще не успели установить if len(publicKey) == 0 { // пока не собрана цепочка блоков не даем ввести ключ infoBlock, err := c.DCDB.GetInfoBlock() if err != nil { return "{\"result\":0}", err } // если последний блок не старше 2-х часов wTime := int64(2) if c.ConfigIni["test_mode"] == "1" { wTime = 2 * 365 * 24 } log.Debug("%v/%v/%v", time.Now().Unix(), utils.StrToInt64(infoBlock["time"]), wTime) if (time.Now().Unix() - utils.StrToInt64(infoBlock["time"])) < 3600*wTime { // проверим, верный ли установочный пароль, если он, конечно, есть setupPassword_, err := c.Single("SELECT setup_password FROM config").String() if err != nil { return "{\"result\":0}", err } if len(setupPassword_) > 0 && setupPassword_ != string(utils.DSha256(setupPassword)) { log.Debug(setupPassword_, string(utils.DSha256(setupPassword)), setupPassword) return "{\"result\":0}", nil } publicKey := utils.MakeAsn1(n, e) log.Debug("new key", string(publicKey)) userId, err := c.GetUserIdByPublicKey(publicKey) if err != nil { return "{\"result\":0}", err } // получим данные для подписи forSign, err := c.DCDB.GetDataAuthorization(hash) if err != nil { return "{\"result\":0}", err } log.Debug("forSign", forSign) log.Debug("publicKey %x\n", utils.HexToBin(publicKey)) log.Debug("sign_", string(sign)) // проверим подпись resultCheckSign, err := utils.CheckSign([][]byte{utils.HexToBin(publicKey)}, forSign, utils.HexToBin(sign), true) if err != nil { return "{\"result\":0}", err } if !resultCheckSign { return "{\"result\":0}", nil } if len(userId) > 0 { err := c.InsertIntoMyKey("", publicKey, "0") if err != nil { return "{\"result\":0}", err } minerId, err := c.GetMinerId(utils.StrToInt64(userId)) if err != nil { return "{\"result\":0}", err } //myUserId, err := c.GetMyUserId("") //if myUserId > 0 { if minerId > 0 { err = c.ExecSql("UPDATE my_table SET user_id = ?, miner_id = ?, status = 'miner'", userId, minerId) if err != nil { return "{\"result\":0}", err } } else { err = c.ExecSql("UPDATE my_table SET user_id = ?, status = 'user'", userId) if err != nil { return "{\"result\":0}", err } } //} else { // c.ExecSql("INSERT INTO my_table (user_id, status) VALUES (?, 'user')", userId) //} // возможно юзер хочет сохранить свой ключ if len(private_key) > 0 { c.ExecSql("UPDATE my_keys SET private_key = ? WHERE block_id = (SELECT max(block_id) FROM my_keys)", private_key) } } else { checkError = true } } else { checkError = true } } else { log.Debug("RemoteAddr %s", RemoteAddr) hash = utils.Md5(c.r.Header.Get("User-Agent") + RemoteAddr) log.Debug("hash %s", hash) // получим данные для подписи forSign, err := c.DCDB.GetDataAuthorization(hash) log.Debug("forSign", forSign) log.Debug("publicKey %x\n", string(publicKey)) log.Debug("sign_", string(sign)) // проверим подпись resultCheckSign, err := utils.CheckSign([][]byte{publicKey}, forSign, utils.HexToBin(sign), true) if err != nil { return "{\"result\":0}", err } if !resultCheckSign { return "{\"result\":0}", nil } } if checkError { return "{\"result\":0}", nil } else { myUserId, err := c.DCDB.GetMyUserId("") if myUserId == 0 { myUserId = -1 } if err != nil { return "{\"result\":0}", err } c.sess.Delete("restricted") c.sess.Set("user_id", myUserId) // если уже пришел блок, в котором зареган ключ юзера if myUserId != -1 { public_key, err := c.DCDB.GetUserPublicKey(myUserId) if err != nil { return "{\"result\":0}", err } // паблик кей в сессии нужен чтобы выбрасывать юзера, если ключ изменился c.sess.Set("public_key", string(utils.BinToHex(public_key))) // возможно юзер хочет сохранить свой ключ if len(private_key) > 0 { c.ExecSql("UPDATE my_keys SET private_key = ? WHERE block_id = (SELECT max(block_id) FROM my_keys)", private_key) } AdminUserId, err := c.DCDB.GetAdminUserId() if err != nil { return "{\"result\":0}", err } if AdminUserId == myUserId { c.sess.Set("admin", int64(1)) } return "{\"result\":1}", nil } } } return "{\"result\":0}", nil }
func (a *AvailablekeyStruct) GetAvailableKey() (int64, string, error) { community, err := a.GetCommunityUsers() if err != nil { return 0, "", utils.ErrInfo(err) } // запрещено менять ключ таким методом если в my_table уже есть статус if len(community) == 0 { status, err := a.Single("SELECT status FROM my_table").String() if err != nil { return 0, "", utils.ErrInfo(err) } if status != "my_pending" { return 0, "", utils.ErrInfo(errors.New("my_table not null")) } } var keys []string for i := 0; i < 10; i++ { keysStr, err := utils.GetHttpTextAnswer("http://dcoin.club/keys") if err != nil { return 0, "", utils.ErrInfo(err) } //keysStr = strings.Replace(keysStr, "\n", "", -1) r, _ := regexp.Compile("(?s)-----BEGIN RSA PRIVATE KEY-----(.*?)-----END RSA PRIVATE KEY-----") keys = r.FindAllString(keysStr, -1) for i := range keys { j := rand.Intn(i + 1) keys[i], keys[j] = keys[j], keys[i] } if len(keys) > 0 { break } else { utils.Sleep(5) } } for _, key := range keys { userId, pubKey, err := a.checkAvailableKey(key) if err != nil { log.Error("%s", utils.ErrInfo(err)) // тут ошибка - это нормально } log.Debug("checkAvailableKey userId: %v", userId) if userId > 0 { // запишем приватный ключ в БД, чтобы можно было подписать тр-ию на смену ключа myPref := "" log.Debug("schema_ 0") if len(community) > 0 { schema_ := &schema.SchemaStruct{} schema_.DCDB = a.DCDB schema_.DbType = a.ConfigIni["db_type"] schema_.PrefixUserId = int(userId) schema_.GetSchema() myPref = utils.Int64ToStr(userId) + "_" err = a.ExecSql("INSERT INTO "+myPref+"my_table (user_id, status, email) VALUES (?, ?, ?)", userId, "waiting_set_new_key", a.Email) if err != nil { return 0, "", utils.ErrInfo(err) } err = a.ExecSql("INSERT INTO community ( user_id ) VALUES ( ? )", userId) if err != nil { return 0, "", utils.ErrInfo(err) } } else { err = a.ExecSql("UPDATE my_table SET user_id = ?, status = ?", userId, "waiting_set_new_key") if err != nil { return 0, "", utils.ErrInfo(err) } } log.Debug("schema_ 1") // пишем приватный в my_keys т.к. им будем подписывать тр-ию на смену ключа err = a.ExecSql("INSERT INTO "+myPref+"my_keys (private_key, public_key, status, block_id) VALUES (?, [hex], ?, ?)", key, pubKey, "approved", 1) if err != nil { return 0, "", utils.ErrInfo(err) } log.Debug("GenKeys 0") newPrivKey, newPubKey := utils.GenKeys() log.Debug("GenKeys 1") // сразу генерируем новый ключ и пишем приватный временно в my_keys, чтобы можно было выдавать юзеру для скачивания err = a.ExecSql("INSERT INTO "+myPref+"my_keys (private_key, public_key, status) VALUES (?, ?, ?)", newPrivKey, utils.HexToBin([]byte(newPubKey)), "my_pending") if err != nil { return 0, "", utils.ErrInfo(err) } log.Debug("return userId %d", userId) return userId, pubKey, nil } } return 0, "", nil }
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 }
func MaxOtherCurrenciesGenerator(chBreaker chan bool, chAnswer chan string) { defer func() { if r := recover(); r != nil { log.Error("daemon Recovered", r) panic(r) } }() const GoroutineName = "MaxOtherCurrenciesGenerator" d := new(daemon) d.DCDB = DbConnect(chBreaker, chAnswer, GoroutineName) if d.DCDB == nil { return } d.goRoutineName = GoroutineName d.chAnswer = chAnswer d.chBreaker = chBreaker if utils.Mobile() { d.sleepTime = 3600 } else { d.sleepTime = 60 } if !d.CheckInstall(chBreaker, chAnswer, GoroutineName) { return } d.DCDB = DbConnect(chBreaker, chAnswer, GoroutineName) if d.DCDB == nil { return } err = d.notMinerSetSleepTime(1800) if err != nil { log.Error("%v", err) return } BEGIN: for { log.Info(GoroutineName) MonitorDaemonCh <- []string{GoroutineName, utils.Int64ToStr(utils.Time())} // проверим, не нужно ли нам выйти из цикла if CheckDaemonsRestart(chBreaker, chAnswer, GoroutineName) { break BEGIN } err, restart := d.dbLock() if restart { break BEGIN } if err != nil { if d.dPrintSleep(err, d.sleepTime) { break BEGIN } continue BEGIN } blockId, err := d.GetBlockId() if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } if blockId == 0 { if d.unlockPrintSleep(utils.ErrInfo("blockId == 0"), d.sleepTime) { break BEGIN } continue BEGIN } _, _, myMinerId, _, _, _, err := d.TestBlock() if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } // а майнер ли я ? if myMinerId == 0 { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } variables, err := d.GetAllVariables() curTime := utils.Time() totalCountCurrencies, err := d.GetCountCurrencies() if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } // проверим, прошло ли 2 недели с момента последнего обновления pctTime, err := d.Single("SELECT max(time) FROM max_other_currencies_time").Int64() if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } if curTime-pctTime <= variables.Int64["new_max_other_currencies"] { if d.unlockPrintSleep(utils.ErrInfo("14 day error"), d.sleepTime) { break BEGIN } continue BEGIN } // берем все голоса maxOtherCurrenciesVotes := make(map[int64][]map[int64]int64) rows, err := d.Query("SELECT currency_id, count, count(user_id) as votes FROM votes_max_other_currencies GROUP BY currency_id, count ORDER BY currency_id, count ASC") if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } for rows.Next() { var currency_id, count, votes int64 err = rows.Scan(¤cy_id, &count, &votes) if err != nil { rows.Close() if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } maxOtherCurrenciesVotes[currency_id] = append(maxOtherCurrenciesVotes[currency_id], map[int64]int64{count: votes}) } rows.Close() newMaxOtherCurrenciesVotes := make(map[string]int64) for currencyId, countAndVotes := range maxOtherCurrenciesVotes { newMaxOtherCurrenciesVotes[utils.Int64ToStr(currencyId)] = utils.GetMaxVote(countAndVotes, 0, totalCountCurrencies, 10) } jsonData, err := json.Marshal(newMaxOtherCurrenciesVotes) _, myUserId, _, _, _, _, err := d.TestBlock() forSign := fmt.Sprintf("%v,%v,%v,%s", utils.TypeInt("NewMaxOtherCurrencies"), curTime, myUserId, jsonData) 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("NewMaxOtherCurrencies"), 1) data = append(data, utils.DecToBin(curTime, 4)...) data = append(data, utils.EncodeLengthPlusData(utils.Int64ToByte(myUserId))...) data = append(data, utils.EncodeLengthPlusData(jsonData)...) data = append(data, utils.EncodeLengthPlusData([]byte(binSign))...) err = d.InsertReplaceTxInQueue(data) if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } p := new(dcparser.Parser) p.DCDB = d.DCDB err = p.TxParser(utils.HexToBin(utils.Md5(data)), data, true) if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } d.dbUnlock() if d.dSleep(d.sleepTime) { break BEGIN } } log.Debug("break BEGIN %v", GoroutineName) }
func (c *Controller) SignUpInPool() (string, error) { c.w.Header().Set("Access-Control-Allow-Origin", "*") if !c.Community { return "", utils.JsonAnswer("Not pool", "error").Error() } c.r.ParseForm() var userId int64 var codeSign string if c.SessUserId <= 0 { // запрос пришел с десктопного кошелька юзера codeSign = c.r.FormValue("code_sign") if !utils.CheckInputData(codeSign, "hex_sign") { return "", utils.JsonAnswer("Incorrect code_sign", "error").Error() } userId = utils.StrToInt64(c.r.FormValue("user_id")) if !utils.CheckInputData(userId, "int64") { return "", utils.JsonAnswer("Incorrect userId", "error").Error() } // получим данные для подписи var hash []byte RemoteAddr := utils.RemoteAddrFix(c.r.RemoteAddr) re := regexp.MustCompile(`(.*?):[0-9]+$`) match := re.FindStringSubmatch(RemoteAddr) if len(match) != 0 { RemoteAddr = match[1] } log.Debug("RemoteAddr %s", RemoteAddr) hash = utils.Md5(c.r.Header.Get("User-Agent") + RemoteAddr) log.Debug("hash %s", hash) forSign, err := c.GetDataAuthorization(hash) log.Debug("forSign: %v", forSign) publicKey, err := c.GetUserPublicKey(userId) log.Debug("publicKey: %x", publicKey) if err != nil { return "", utils.JsonAnswer(utils.ErrInfo(err), "error").Error() } // проверим подпись resultCheckSign, err := utils.CheckSign([][]byte{[]byte(publicKey)}, forSign, utils.HexToBin([]byte(codeSign)), true) if err != nil { return "", utils.JsonAnswer(utils.ErrInfo(err), "error").Error() } if !resultCheckSign { return "", utils.JsonAnswer("Incorrect codeSign", "error").Error() } } else { // запрос внутри пула userId = c.SessUserId } /*e:=c.r.FormValue("e") n:=c.r.FormValue("n") if len(e) == 0 || len(n) == 0 { result, _ := json.Marshal(map[string]string{"error": c.Lang["pool_error"]}) return "", errors.New(string(result)) }*/ email := c.r.FormValue("email") if !utils.ValidateEmail(email) { return "", utils.JsonAnswer("Incorrect email", "error").Error() } nodePrivateKey := c.r.FormValue("node_private_key") if !utils.CheckInputData(nodePrivateKey, "private_key") { return "", utils.JsonAnswer("Incorrect private_key", "error").Error() } //publicKey := utils.MakeAsn1([]byte(n), []byte(e)) log.Debug("3") // если мест в пуле нет, то просто запишем юзера в очередь pool_max_users, err := c.Single("SELECT pool_max_users FROM config").Int() if err != nil { return "", utils.JsonAnswer(utils.ErrInfo(err), "error").Error() } if len(c.CommunityUsers) >= pool_max_users { err = c.ExecSql("INSERT INTO pool_waiting_list ( email, time, user_id ) VALUES ( ?, ?, ? )", email, utils.Time(), userId) if err != nil { return "", utils.JsonAnswer(utils.ErrInfo(err), "error").Error() } return "", utils.JsonAnswer(c.Lang["pool_is_full"], "error").Error() } // регистрируем юзера в пуле // вначале убедимся, что такой user_id у нас уже не зареган community, err := c.Single("SELECT user_id FROM community WHERE user_id = ?", userId).Int64() if err != nil { return "", utils.JsonAnswer(utils.ErrInfo(err), "error").Error() } if community != 0 { return utils.JsonAnswer(c.Lang["pool_user_id_is_busy"], "success").String(), nil } err = c.ExecSql("INSERT INTO community ( user_id ) VALUES ( ? )", userId) if err != nil { return "", utils.JsonAnswer(utils.ErrInfo(err), "error").Error() } schema_ := &schema.SchemaStruct{} schema_.DCDB = c.DCDB schema_.DbType = c.ConfigIni["db_type"] schema_.PrefixUserId = int(userId) schema_.GetSchema() prefix := utils.Int64ToStr(userId) + "_" minerId, err := c.GetMinerId(userId) if err != nil { return "", utils.JsonAnswer(utils.ErrInfo(err), "error").Error() } if minerId > 0 { err = c.ExecSql("INSERT INTO "+prefix+"my_table ( user_id, miner_id, status, email ) VALUES (?, ?, ?, ?)", userId, minerId, "miner", email) if err != nil { return "", utils.JsonAnswer(utils.ErrInfo(err), "error").Error() } } else { err = c.ExecSql("INSERT INTO "+prefix+"my_table ( user_id, status, email ) VALUES (?, ?, ?)", userId, "miner", email) if err != nil { return "", utils.JsonAnswer(utils.ErrInfo(err), "error").Error() } } publicKey, err := c.GetUserPublicKey(userId) err = c.ExecSql("INSERT INTO "+prefix+"my_keys ( public_key, status ) VALUES ( [hex], 'approved' )", utils.BinToHex(publicKey)) if err != nil { return "", utils.JsonAnswer(utils.ErrInfo(err), "error").Error() } nodePublicKey, err := utils.GetPublicFromPrivate(nodePrivateKey) if err != nil { return "", utils.JsonAnswer(utils.ErrInfo(err), "error").Error() } err = c.ExecSql("INSERT INTO "+prefix+"my_node_keys ( private_key, public_key ) VALUES ( ?, [hex] )", nodePrivateKey, nodePublicKey) if err != nil { return "", utils.JsonAnswer(utils.ErrInfo(err), "error").Error() } c.sess.Delete("restricted") return utils.JsonAnswer(c.Lang["pool_sign_up_success"], "success").String(), nil }