예제 #1
0
파일: new_user.go 프로젝트: dzyk/dcoin-go
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)
	}

}
예제 #2
0
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)
	}

}
예제 #3
0
파일: e_gate_ik.go 프로젝트: dzyk/dcoin-go
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
}
예제 #4
0
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)

}
예제 #5
0
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
}
예제 #6
0
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)
}
예제 #7
0
파일: type11.go 프로젝트: dzyk/dcoin-go
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"))
	}
}
예제 #8
0
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
}
예제 #9
0
/*
 * Каждые 2 недели собираем инфу о голосах за % и создаем тр-ию, которая
 * попадет в DC сеть только, если мы окажемся генератором блока
 * */
func ReductionGenerator(chBreaker chan bool, chAnswer chan string) {
	defer func() {
		if r := recover(); r != nil {
			log.Error("daemon Recovered", r)
			panic(r)
		}
	}()

	const GoroutineName = "ReductionGenerator"
	d := new(daemon)
	d.DCDB = DbConnect(chBreaker, chAnswer, GoroutineName)
	if d.DCDB == nil {
		return
	}
	d.goRoutineName = GoroutineName
	d.chAnswer = chAnswer
	d.chBreaker = chBreaker
	if utils.Mobile() {
		d.sleepTime = 3600
	} else {
		d.sleepTime = 60
	}
	if !d.CheckInstall(chBreaker, chAnswer, GoroutineName) {
		return
	}
	d.DCDB = DbConnect(chBreaker, chAnswer, GoroutineName)
	if d.DCDB == nil {
		return
	}

	err = d.notMinerSetSleepTime(1800)
	if err != nil {
		log.Error("%v", err)
		return
	}

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

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

		err, restart := d.dbLock()
		if restart {
			break BEGIN
		}
		if err != nil {
			if d.dPrintSleep(err, d.sleepTime) {
				break BEGIN
			}
			continue BEGIN
		}

		blockId, err := d.GetBlockId()
		if err != nil {
			if d.unlockPrintSleep(err, d.sleepTime) {
				break BEGIN
			}
			continue BEGIN
		}
		if blockId == 0 {
			if d.unlockPrintSleep(errors.New("blockId == 0"), d.sleepTime) {
				break BEGIN
			}
			continue BEGIN
		}

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

		// ===== ручное урезание денежной массы
		// получаем кол-во обещанных сумм у разных юзеров по каждой валюте. start_time есть только у тех, у кого статус mining/repaid
		promisedAmount, err := d.GetMap(`
				SELECT currency_id, count(user_id) as count
				FROM (
						SELECT currency_id, user_id
						FROM promised_amount
						WHERE start_time < ?  AND
									 del_block_id = 0 AND
									 del_mining_block_id = 0 AND
									 status IN ('mining', 'repaid')
						GROUP BY  user_id, currency_id
						) as t1
				GROUP BY  currency_id`, "currency_id", "count", (curTime - variables.Int64["min_hold_time_promise_amount"]))
		if err != nil {
			if d.unlockPrintSleep(err, d.sleepTime) {
				break BEGIN
			}
			continue BEGIN
		}
		log.Info("%v", "promisedAmount", promisedAmount)

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

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

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

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

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

		log.Debug("sumWallets", sumWallets)

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

		log.Debug("sumPromisedAmount", sumPromisedAmount)

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

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

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

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

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

			err = d.InsertReplaceTxInQueue(data)
			if err != nil {
				if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) {
					break BEGIN
				}
				continue BEGIN
			}

			// и не закрывая main_lock переводим нашу тр-ию в verified=1, откатив все несовместимые тр-ии
			// таким образом у нас будут в блоке только актуальные голоса.
			// а если придет другой блок и станет verified=0, то эта тр-ия просто удалится.

			p := new(dcparser.Parser)
			p.DCDB = d.DCDB
			err = p.TxParser(utils.HexToBin(utils.Md5(data)), data, true)
			if err != nil {
				if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) {
					break BEGIN
				}
				continue BEGIN
			}
		}
		d.dbUnlock()

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

}
예제 #10
0
파일: type1.go 프로젝트: dzyk/dcoin-go
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
				}
			}
		}
	}
}
예제 #11
0
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
	}
}
예제 #12
0
파일: exchange.go 프로젝트: dzyk/dcoin-go
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, &currencyId, &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, &currencyId, &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, &currencyId, &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)
}
예제 #13
0
/*
 * Каждые 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(&currency_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(&currency_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)
}
예제 #14
0
파일: type12.go 프로젝트: dzyk/dcoin-go
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"))
	}
}
예제 #15
0
파일: check_sign.go 프로젝트: dzyk/dcoin-go
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
}
예제 #16
0
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
}
예제 #17
0
func (c *Controller) GetChatMessages() (string, error) {

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

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

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

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

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

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

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

	return string(resultJson), nil
}
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(&currency_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)
}
예제 #19
0
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
}