예제 #1
0
func (p *Parser) ChangePrimaryKeyFront() error {

	err := p.generalCheck()
	if err != nil {
		return p.ErrInfo(err)
	}

	if !utils.CheckInputData(p.newPublicKeysHex[0], "public_key") {
		return p.ErrInfo("public_key")
	}
	if len(p.newPublicKeysHex[1]) > 0 && !utils.CheckInputData(p.newPublicKeysHex[1], "public_key") {
		return p.ErrInfo("public_key 1")
	}
	if len(p.newPublicKeysHex[2]) > 0 && !utils.CheckInputData(p.newPublicKeysHex[2], "public_key") {
		return p.ErrInfo("public_key 2")
	}

	forSign := fmt.Sprintf("%s,%s,%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.newPublicKeysHex[0], p.newPublicKeysHex[1], p.newPublicKeysHex[2])
	CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false)
	if err != nil {
		return p.ErrInfo(err)
	}
	if !CheckSignResult {
		return p.ErrInfo("incorrect sign")
	}

	err = p.limitRequest(p.Variables.Int64["limit_primary_key"], "primary_key", p.Variables.Int64["limit_primary_key_period"])
	if err != nil {
		return p.ErrInfo(err)
	}
	return nil
}
예제 #2
0
파일: change_ca.go 프로젝트: dzyk/dcoin-go
func (p *Parser) ChangeCaFront() error {

	err := p.generalCheck()
	if err != nil {
		return p.ErrInfo(err)
	}

	if !utils.CheckInputData(p.TxMaps.String["ca1"], "ca_url") && p.TxMaps.String["ca1"] != "0" {
		return fmt.Errorf("incorrect ca1")
	}
	if !utils.CheckInputData(p.TxMaps.String["ca2"], "ca_url") && p.TxMaps.String["ca2"] != "0" {
		return fmt.Errorf("incorrect ca2")
	}
	if !utils.CheckInputData(p.TxMaps.String["ca3"], "ca_url") && p.TxMaps.String["ca3"] != "0" {
		return fmt.Errorf("incorrect ca3")
	}

	forSign := fmt.Sprintf("%s,%s,%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["ca1"], p.TxMap["ca2"], p.TxMap["ca3"])
	CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false)
	if err != nil {
		return p.ErrInfo(err)
	}
	if !CheckSignResult {
		return p.ErrInfo("incorrect sign")
	}

	err = p.limitRequest(consts.LIMIT_CHANGE_CA, "change_ca", consts.LIMIT_CHANGE_CA_PERIOD)
	if err != nil {
		return p.ErrInfo(err)
	}
	return nil
}
예제 #3
0
파일: save_host.go 프로젝트: dzyk/dcoin-go
func (c *Controller) SaveHost() (string, error) {

	if c.SessRestricted != 0 {
		return "", utils.ErrInfo(errors.New("Permission denied"))
	}

	c.r.ParseForm()
	http_host := c.r.FormValue("http_host")
	if len(http_host) > 0 && http_host[len(http_host)-1:] != "/" {
		http_host += "/"
	}
	tcp_host := c.r.FormValue("tcp_host")

	if !utils.CheckInputData(http_host, "http_host") {
		return `{"error":"1"}`, nil
	}
	if !utils.CheckInputData(tcp_host, "tcp_host") {
		return `{"error":"1"}`, nil
	}

	err := c.ExecSql("UPDATE "+c.MyPrefix+"my_table SET http_host = ?, tcp_host = ?", http_host, tcp_host)
	if err != nil {
		return "", utils.ErrInfo(err)
	}

	return `{"error":"0"}`, nil
}
예제 #4
0
func (p *Parser) VotesNodeNewMinerFront() error {
	err := p.generalCheck()
	if err != nil {
		return p.ErrInfo(err)
	}
	// является ли данный юзер майнером
	err = p.checkMiner(p.TxUserID)
	if err != nil {
		return err
	}

	if !utils.CheckInputData(p.TxMap["result"], "vote") {
		return utils.ErrInfoFmt("incorrect vote")
	}
	// получим public_key
	p.nodePublicKey, err = p.GetNodePublicKey(p.TxUserID)
	if len(p.nodePublicKey) == 0 {
		return utils.ErrInfoFmt("incorrect user_id len(nodePublicKey) = 0")
	}

	if !utils.CheckInputData(p.TxMap["vote_id"], "bigint") {
		return utils.ErrInfoFmt("incorrect bigint")
	}

	forSign := fmt.Sprintf("%s,%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["vote_id"], p.TxMap["result"])
	CheckSignResult, err := utils.CheckSign([][]byte{p.nodePublicKey}, forSign, p.TxMap["sign"], true)
	if err != nil {
		return p.ErrInfo(err)
	}
	if !CheckSignResult {
		return utils.ErrInfoFmt("incorrect sign")
	}

	// проверим, верно ли указан ID и не закончилось ли голосование
	id, err := p.Single("SELECT id FROM votes_miners WHERE id = ? AND type = 'node_voting' AND votes_end = 0", p.TxMaps.Int64["vote_id"]).Int64()
	if err != nil {
		return p.ErrInfo(err)
	}
	if id == 0 {
		return p.ErrInfo(fmt.Errorf("voting is over"))
	}

	// проверим, не повторное ли это голосование данного юзера
	num, err := p.Single("SELECT count(user_id) FROM log_votes WHERE user_id = ? AND voting_id = ? AND type = 'votes_miners'", p.TxMaps.Int64["user_id"], p.TxMaps.Int64["vote_id"]).Int64()
	if err != nil {
		return p.ErrInfo(err)
	}
	if num > 0 {
		return utils.ErrInfoFmt("double voting")
	}

	// нод не должен голосовать более X раз за сутки, чтобы не было доса
	err = p.limitRequest(p.Variables.Int64["node_voting"], "votes_nodes", p.Variables.Int64["node_voting_period"])
	if err != nil {
		return p.ErrInfo(err)
	}

	return nil
}
예제 #5
0
func (p *Parser) VotesMinerFront() error {
	err := p.generalCheck()
	if err != nil {
		return p.ErrInfo(err)
	}

	if !utils.CheckInputData(p.TxMap["vote_id"], "bigint") {
		return p.ErrInfo("incorrect vote_id")
	}
	if !utils.CheckInputData(p.TxMap["result"], "vote") {
		return p.ErrInfo("incorrect vote_id")
	}
	if !utils.CheckInputData(p.TxMap["comment"], "votes_comment") {
		return p.ErrInfo("incorrect comment")
	}

	// является ли данный юзер майнером
	err = p.checkMiner(p.TxUserID)
	if err != nil {
		return p.ErrInfo(err)
	}

	// проверим, верно ли указан ID и не закончилось ли голосование
	id, err := p.Single("SELECT id FROM votes_miners WHERE id = ? AND type = 'user_voting' AND votes_end = 0", p.TxMaps.Int64["vote_id"]).Int()
	if err != nil {
		return p.ErrInfo(err)
	}
	if id == 0 {
		return p.ErrInfo("voting is over")
	}

	// проверим, не повторное ли это голосование данного юзера
	num, err := p.Single("SELECT count(user_id) FROM log_votes WHERE user_id = ? AND voting_id = ? AND type = 'votes_miners'", p.TxMaps.Int64["user_id"], p.TxMaps.Int64["vote_id"]).Int()
	if err != nil {
		return p.ErrInfo("double voting")
	}
	if num > 0 {
		return p.ErrInfo("double voting")
	}

	forSign := fmt.Sprintf("%s,%s,%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["vote_id"], p.TxMap["result"], p.TxMap["comment"])
	CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false)
	if err != nil {
		return p.ErrInfo(err)
	}
	if !CheckSignResult {
		return p.ErrInfo("incorrect sign")
	}

	// защита от доса
	err = p.maxDayVotes()
	if err != nil {
		return p.ErrInfo(err)
	}

	return nil
}
예제 #6
0
func (c *Controller) RewritePrimaryKeySave() (string, error) {

	if !c.NodeAdmin || c.SessRestricted != 0 {
		return "", utils.ErrInfo(errors.New("Permission denied"))
	}

	if len(c.r.FormValue("n")) > 0 {

		c.r.ParseForm()
		n := []byte(c.r.FormValue("n"))
		e := []byte(c.r.FormValue("e"))
		if !utils.CheckInputData(n, "hex") {
			return "", utils.ErrInfo(errors.New("incorrect n"))
		}
		if !utils.CheckInputData(e, "hex") {
			return "", utils.ErrInfo(errors.New("incorrect e"))
		}
		publicKey := utils.MakeAsn1(n, e)

		// проверим, есть ли вообще такой публичный ключ
		userId, err := c.Single("SELECT user_id FROM users WHERE hex(public_key_0) = ?", publicKey).Int64()
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		if userId == 0 {
			return "", utils.ErrInfo(errors.New("incorrect public_key"))
		}

		// может быть юзер уже майнер?
		minerId, err := c.GetMinerId(userId)
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		status := ""
		if minerId > 0 {
			status = "miner"
		} else {
			status = "user"
		}

		err = c.ExecSql(`DELETE FROM my_keys`)
		if err != nil {
			return "", utils.ErrInfo(err)
		}

		err = c.ExecSql(`INSERT INTO `+c.MyPrefix+`my_keys (public_key, status) VALUES ([hex], ?)`, publicKey, "approved")
		if err != nil {
			return "", utils.ErrInfo(err)
		}

		err = c.ExecSql(`UPDATE `+c.MyPrefix+`my_table SET user_id = ?, miner_id = ?, status = ?`, userId, minerId, status)
		if err != nil {
			return "", utils.ErrInfo(err)
		}
	}
	return `{"success":"success"}`, nil
}
예제 #7
0
파일: e_withdraw.go 프로젝트: dzyk/dcoin-go
func (c *Controller) EWithdraw() (string, error) {

	if c.SessUserId == 0 {
		return "", errors.New(c.Lang["sign_up_please"])
	}

	c.r.ParseForm()
	currencyId := utils.StrToInt64(c.r.FormValue("currency_id"))
	if !utils.CheckInputData(c.r.FormValue("amount"), "amount") {
		return "", fmt.Errorf("incorrect amount")
	}
	method := c.r.FormValue("method")
	if !utils.CheckInputData(method, "method") {
		return "", fmt.Errorf("incorrect method")
	}
	account := c.r.FormValue("account")
	if !utils.CheckInputData(account, "account") {
		return "", fmt.Errorf("incorrect account")
	}
	amount := utils.StrToFloat64(c.r.FormValue("amount"))

	curTime := utils.Time()

	// нужно проверить, есть ли нужная сумма на счету юзера
	userAmount := utils.EUserAmountAndProfit(c.SessUserId, currencyId)
	if userAmount < amount {
		return "", fmt.Errorf("%s (%f<%f)", c.Lang["not_enough_money"], userAmount, amount)
	}
	if method != "Dcoin" && currencyId < 1000 {
		return "", fmt.Errorf("incorrect method")
	}

	err := userLock(c.SessUserId)
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	err = c.ExecSql(`UPDATE e_wallets SET amount = ?, last_update = ? WHERE user_id = ? AND currency_id = ?`, userAmount-amount, curTime, c.SessUserId, currencyId)
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	var commission float64
	if method == "Dcoin" {
		commission = utils.StrToFloat64(c.EConfig["dc_commission"])
	} else if method == "Perfect-money" {
		commission = utils.StrToFloat64(c.EConfig["pm_commission"])
	}
	wdAmount := utils.ClearNull(utils.Float64ToStr(amount*(1-commission/100)), 2)

	err = c.ExecSql(`INSERT INTO e_withdraw (open_time, user_id, currency_id, account, amount, wd_amount, method) VALUES (?, ?, ?, ?, ?, ?, ?)`, curTime, c.SessUserId, currencyId, account, amount, wdAmount, method)
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	userUnlock(c.SessUserId)

	return utils.JsonAnswer(c.Lang["request_is_created"], "success").String(), nil
}
예제 #8
0
파일: e_pages.go 프로젝트: dzyk/dcoin-go
func (c *Controller) EPages() (string, error) {

	var err error

	var title, text string
	if len(c.Parameters["page"]) > 0 {
		if !utils.CheckInputData(c.Parameters["page"], "string") {
			return "", utils.ErrInfo(err)
		}
		data, err := c.OneRow(`SELECT title, text from e_pages WHERE name = ? AND lang = ?`, c.Parameters["page"], c.LangInt).String()
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		title = data["title"]
		text = data["text"]
	}

	TemplateStr, err := makeTemplate("e_pages", "ePages", &ePages{
		Lang:  c.Lang,
		Title: title,
		Text:  text})
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	return TemplateStr, nil
}
예제 #9
0
파일: e_redirect.go 프로젝트: dzyk/dcoin-go
func (c *Controller) ERedirect() (string, error) {

	c.r.ParseForm()
	token := c.r.FormValue("FormToken")
	amount := c.r.FormValue("FormExAmount")
	buyCurrencyId := utils.StrToInt64(c.r.FormValue("FormDC"))

	if !utils.CheckInputData(token, "string") {
		return "", errors.New("incorrect data")
	}

	// order_id занесем когда поуступят деньги в платежной системе
	err := c.ExecSql(`UPDATE e_tokens SET buy_currency_id = ?, amount_fiat = ? WHERE token = ?`, buyCurrencyId, utils.StrToFloat64(c.r.FormValue("FormExAmount")), token)
	if err != nil {
		return "", utils.ErrInfo(err)
	}

	tokenId, err := c.Single(`SELECT id FROM e_tokens WHERE token = ?`, token).String()
	if err != nil {
		return "", utils.ErrInfo(err)
	}

	TemplateStr, err := makeTemplate("e_redirect", "eRedirect", &ERedirectPage{
		Lang:    c.Lang,
		EConfig: c.EConfig,
		TokenId: tokenId,
		EURL:    c.EURL,
		MDesc:   base64.StdEncoding.EncodeToString([]byte("token-" + tokenId)),
		Amount:  amount})
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	return TemplateStr, nil
}
예제 #10
0
func (p *Parser) UserAvatarFront() error {

	err := p.generalCheck()
	if err != nil {
		return p.ErrInfo(err)
	}

	verifyData := map[string]string{"name": "user_name"}
	err = p.CheckInputData(verifyData)
	if err != nil {
		return p.ErrInfo(err)
	}
	if !utils.CheckInputData(p.TxMaps.String["avatar"], "img_url") && p.TxMaps.String["avatar"] != "0" {
		return fmt.Errorf("incorrect avatar")
	}

	forSign := fmt.Sprintf("%s,%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["name"], p.TxMap["avatar"])
	CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false)
	if err != nil {
		return p.ErrInfo(err)
	}
	if !CheckSignResult {
		return p.ErrInfo("incorrect sign")
	}

	err = p.limitRequest(consts.LIMIT_USER_AVATAR, "user_avatar", consts.LIMIT_USER_AVATAR_PERIOD)
	if err != nil {
		return p.ErrInfo(err)
	}
	return nil
}
예제 #11
0
func (c *Controller) CheckCfCurrency() (string, error) {

	if c.SessRestricted != 0 {
		return "", utils.ErrInfo(errors.New("Permission denied"))
	}

	c.r.ParseForm()
	projectCurrencyName := c.r.FormValue("project_currency_name")
	if !utils.CheckInputData(projectCurrencyName, "cf_currency_name") {
		return "", errors.New("incorrect project_currency_name")
	}

	// проверим, не занято ли имя валюты
	currency, err := c.Single("SELECT id FROM cf_projects WHERE project_currency_name = ? AND close_block_id = 0 AND del_block_id = 0", projectCurrencyName).Int64()
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	if currency > 0 {
		return `{"error":"` + c.Lang["currency_name_busy"] + `"}`, nil
	}

	// проверим, не занято ли имя валюты
	currency, err = c.Single("SELECT id FROM cf_currency WHERE name = ?", projectCurrencyName).Int64()
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	if currency > 0 {
		return `{"error":"` + c.Lang["currency_name_busy"] + `"}`, nil
	}

	return `{"success":"` + c.Lang["name_is_not_occupied"] + `"}`, nil
}
예제 #12
0
파일: new_user.go 프로젝트: dzyk/dcoin-go
func (p *Parser) NewUserFront() error {

	log.Debug("NewUserFront")

	err := p.generalCheck()
	if err != nil {
		return p.ErrInfo(err)
	}

	// является ли данный юзер майнером
	err = p.checkMiner(p.TxUserID)
	if err != nil {
		return p.ErrInfo(err)
	}

	// прошло ли 30 дней с момента регистрации майнера
	err = p.checkMinerNewbie()
	if err != nil {
		return p.ErrInfo(err)
	}

	// чтобы не записали слишком мелкий или слишком крупный ключ
	if !utils.CheckInputData(p.TxMap["public_key_hex"], "public_key") {
		return utils.ErrInfo(fmt.Errorf("incorrect public_key %s", p.TxMap["public_key_hex"]))
	}

	// публичный ключ должен быть без паролей
	if ok, _ := regexp.MatchString("DEK-Info: (.+),(.+)", string(p.TxMap["public_key"])); ok {
		return p.ErrInfo("incorrect public_key")
	}

	forSign := fmt.Sprintf("%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["public_key_hex"])
	CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false)
	if err != nil {
		return p.ErrInfo(err)
	}
	if !CheckSignResult {
		return p.ErrInfo("incorrect sign")
	}

	// один ключ не может быть у двух юзеров
	num, err := p.DCDB.Single("SELECT count(user_id) FROM users WHERE hex(public_key_0) = ? OR hex(public_key_1) = ? OR hex(public_key_2) = ?",
		p.TxMap["public_key_hex"], p.TxMap["public_key_hex"], p.TxMap["public_key_hex"]).Int()
	if num > 0 {
		return p.ErrInfo("exists public_key")
	}
	err = p.getAdminUserId()
	if err != nil {
		return p.ErrInfo(err)
	}
	if utils.BytesToInt64(p.TxMap["user_id"]) == p.AdminUserId {
		err = p.limitRequest(1000, "new_user", 86400)
	} else {
		err = p.limitRequest(p.Variables.Int64["limit_new_user"], "new_user", p.Variables.Int64["limit_new_user_period"])
	}
	if err != nil {
		return p.ErrInfo(err)
	}
	return nil
}
예제 #13
0
파일: abuses.go 프로젝트: dzyk/dcoin-go
func (p *Parser) AbusesFront() error {

	err := p.generalCheck()
	if err != nil {
		return p.ErrInfo(err)
	}

	var abuses map[string]string
	err = json.Unmarshal(p.TxMap["abuses"], &abuses)
	if err != nil {
		return p.ErrInfo(err)
	}
	if len(abuses) > 100 {
		return fmt.Errorf(">100")
	}
	for userId, comment := range abuses {
		if !utils.CheckInputData(userId, "user_id") {
			return fmt.Errorf("incorrect abuses user_id")
		}
		if !utils.CheckInputData(comment, "abuse_comment") {
			return fmt.Errorf("incorrect abuse_comment")
		}
		// является ли данный юзер майнером
		err = p.checkMiner(utils.StrToInt64(userId))
		if err != nil {
			return p.ErrInfo(err)
		}
	}

	forSign := fmt.Sprintf("%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["abuses"])
	CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false)
	if err != nil {
		return p.ErrInfo(err)
	}
	if !CheckSignResult {
		return p.ErrInfo("incorrect sign")
	}

	err = p.limitRequest(p.Variables.Int64["limit_abuses"], "abuses", p.Variables.Int64["limit_abuses_period"])
	if err != nil {
		return p.ErrInfo(err)
	}
	return nil
}
예제 #14
0
func (p *Parser) AdminSpotsFront() error {
	err := p.generalCheckAdmin()
	if err != nil {
		return p.ErrInfo(err)
	}

	if !utils.CheckInputData(p.TxMap["compatibility"], "compatibility") {
		return p.ErrInfo("incorrect compatibility")
	}
	exampleSpots := new(exampleSpotsType)
	if err := json.Unmarshal([]byte(p.TxMap["example_spots"]), &exampleSpots); err != nil {
		return p.ErrInfo("incorrect example_spots")
	}
	if exampleSpots.Face == nil || exampleSpots.Profile == nil {
		return p.ErrInfo("incorrect example_spots")
	}

	segments := new(exampleSpotsType)
	if err := json.Unmarshal([]byte(p.TxMap["segments"]), &segments); err != nil {
		return p.ErrInfo("incorrect segments")
	}
	if segments.Face == nil || segments.Profile == nil {
		return p.ErrInfo("incorrect segments")
	}
	tolerances := new(tolerancesType)
	if err := json.Unmarshal([]byte(p.TxMap["tolerances"]), &tolerances); err != nil {
		return p.ErrInfo("incorrect tolerances")
	}
	if tolerances.Face == nil || tolerances.Profile == nil {
		return p.ErrInfo("incorrect tolerances")
	}
	forSign := fmt.Sprintf("%s,%s,%s,%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["example_spots"], p.TxMap["segments"], p.TxMap["tolerances"], p.TxMap["compatibility"])
	CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false)
	if err != nil {
		return p.ErrInfo(err)
	}
	if !CheckSignResult {
		return p.ErrInfo("incorrect sign")
	}
	return nil
}
예제 #15
0
파일: e_info.go 프로젝트: dzyk/dcoin-go
func (c *Controller) EInfo() (string, error) {

	c.w.Header().Set("Access-Control-Allow-Origin", "*")

	c.r.ParseForm()
	token := c.r.FormValue("token")
	if !utils.CheckInputData(token, "string") {
		return "", errors.New("incorrect token")
	}
	tokenMap, err := c.OneRow(`SELECT * FROM e_tokens WHERE token = ?`, token).String()
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	wallets, err := c.GetAll(`SELECT * FROM e_wallets WHERE user_id = ?`, 100, tokenMap["user_id"])
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	orders, err := c.GetAll(`SELECT * FROM e_orders WHERE user_id = ? ORDER BY time DESC LIMIT 10`, 100, tokenMap["user_id"])
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	withdraw, err := c.GetAll(`SELECT * FROM e_withdraw WHERE user_id = ? ORDER BY open_time DESC LIMIT 10`, 100, tokenMap["user_id"])
	if err != nil {
		return "", utils.ErrInfo(err)
	}

	m := EInfoResult{
		Token:    tokenMap,
		Wallets:  wallets,
		Orders:   orders,
		Withdraw: withdraw,
	}
	jsonData, err := json.Marshal(m)
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	return string(jsonData), nil
}
예제 #16
0
func (c *Controller) CfPagePreview() (string, error) {

	var err error

	txType := "CfComment"
	txTypeId := utils.TypeInt(txType)
	timeNow := time.Now().Unix()

	cfUrl, err := c.GetCfUrl()
	if err != nil {
		return "", utils.ErrInfo(err)
	}

	showHeaders := false
	if len(c.r.FormValue("blurb_img")) > 0 {
		showHeaders = true
	}

	page := c.Parameters["page"]
	if len(page) > 0 {
		if ok, _ := regexp.MatchString(`^(?i)[a-z]{0,10}$`, page); !ok {
			return "", errors.New("incorrect page")
		}
	}
	cfCurrencyName := c.Parameters["onlyCfCurrencyName"]
	if len(page) == 0 {
		page = "home"
	}

	langId := int64(utils.StrToFloat64(c.Parameters["lang_id"]))
	projectId := int64(utils.StrToFloat64(c.Parameters["onlyProjectId"]))
	log.Debug("projectId:", projectId)
	var blurbImg, headImg, descriptionImg, picture, videoType, videoUrlId, newsImg string
	imgBlank := cfUrl + "static/img/blank.png"

	var links [][]string
	if projectId > 0 || len(cfCurrencyName) > 0 {
		if projectId == 0 {
			projectId, err = c.Single("SELECT id FROM cf_projects WHERE project_currency_name = ?", cfCurrencyName).Int64()
			if err != nil {
				return "", utils.ErrInfo(err)
			}
		}
		data := make(map[string]string)
		if langId > 0 {
			data, err = c.OneRow("SELECT * FROM cf_projects_data WHERE project_id = ? AND lang_id = ?", projectId, langId).String()
			if err != nil {
				return "", utils.ErrInfo(err)
			}
		} else { // Если язык не указан, то просто берем первое добавленное описание
			data, err = c.OneRow("SELECT * FROM cf_projects_data WHERE project_id = ? ORDER BY id ASC", projectId).String()
			if err != nil {
				return "", utils.ErrInfo(err)
			}
			langId = utils.StrToInt64(data["lang_id"])
		}
		blurbImg = data["blurb_img"]
		headImg = data["head_img"]
		descriptionImg = data["description_img"]
		picture = data["picture"]
		videoType = data["video_type"]
		videoUrlId = data["video_url_id"]
		newsImg = data["news_img"]
		if len(data["links"]) > 0 && data["links"] != "0" {
			var links_ [][]interface{}
			err = json.Unmarshal([]byte(data["links"]), &links_)
			if err != nil {
				log.Debug("data links:", data["links"])
				return "", utils.ErrInfo(err)
			}
			for _, v := range links_ {
				var l []string
				for _, v2 := range v {
					str := utils.InterfaceToStr(v2)
					if len(str) == 0 {
						return "", utils.ErrInfo(errors.New("Incorrect links"))
					}
					l = append(l, str)
				}
				links = append(links, l)
			}
		}
	} else {
		log.Debug("FormValue", c.r.Form)

		blurbImg = c.r.FormValue("blurb_img")
		headImg = c.r.FormValue("head_img")
		descriptionImg = c.r.FormValue("description_img")
		picture = c.r.FormValue("blurb_img")
		videoType = c.r.FormValue("video_type")
		videoUrlId = c.r.FormValue("video_url_id")
		newsImg = c.r.FormValue("news_img")

		if !utils.CheckInputData(c.r.FormValue("project_id"), "int") {
			return "", errors.New("Incorrect project_id")
		}
		if !utils.CheckInputData(blurbImg, "img_url") {
			blurbImg = imgBlank
		}
		if !utils.CheckInputData(headImg, "img_url") {
			headImg = imgBlank
		}
		if !utils.CheckInputData(descriptionImg, "img_url") {
			descriptionImg = imgBlank
		}
		if !utils.CheckInputData(picture, "img_url") {
			picture = imgBlank
		}
		if !utils.CheckInputData(newsImg, "img_url") {
			newsImg = imgBlank
		}
		if !utils.CheckInputData(videoType, "video_type") {
			videoType = ""
		}
		if !utils.CheckInputData(videoUrlId, "video_url_id") {
			videoUrlId = ""
		}

		if len(c.Parameters["links"]) > 0 {
			var links_ [][]interface{}
			err = json.Unmarshal([]byte(c.Parameters["links"]), &links_)
			if err != nil {
				return "", utils.ErrInfo(err)
			}
			for _, v := range links_ {
				var l []string
				for _, v2 := range v {
					str := utils.InterfaceToStr(v2)
					if len(str) == 0 {
						return "", utils.ErrInfo(errors.New("Incorrect links"))
					}
					l = append(l, str)
				}
				links = append(links, l)
			}
		}
	}

	project, err := c.OneRow("SELECT * FROM cf_projects WHERE id = ?", projectId).String()
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	// сколько дней осталось
	days := utils.Round((utils.StrToFloat64(project["end_time"])-float64(utils.Time()))/86400, 0)
	if days <= 0 {
		days = 0
	}
	project["days"] = utils.Float64ToStr(days)
	if project["close_block_id"] != "0" || project["del_block_id"] != "0" {
		project["ended"] = "1"
	} else {
		project["ended"] = "0"
	}

	// дата старта
	t := time.Unix(utils.StrToInt64(project["start_time"]), 0)
	project["start_date"] = t.Format(c.TimeFormat)

	// в какой валюте идет сбор
	project["currency"] = c.CurrencyList[utils.StrToInt64(project["currency_id"])]

	// на каких языках есть описание
	// для home/news можно скрыть язык
	addSql := ""
	if page == "home" || page == "news" {
		addSql = " AND hide = 0 "
	}
	projectLang, err := c.GetMap(`SELECT id, lang_id FROM cf_projects_data WHERE project_id = ? `+addSql, "id", "lang_id", projectId)

	// сколько собрано средств
	projectFunding, err := c.Single("SELECT sum(amount) FROM cf_funding WHERE project_id  =  ? AND del_block_id  =  0", projectId).Float64()
	if err != nil {
		return "", utils.ErrInfo(err)
	}

	// сколько всего фундеров
	projectCountFunders, err := c.Single("SELECT count(id) FROM cf_funding WHERE project_id  =  ? AND del_block_id  =  0 GROUP BY user_id", projectId).Int64()
	if err != nil {
		return "", utils.ErrInfo(err)
	}

	// список фундеров
	var q string
	if c.ConfigIni["db_type"] == "postgresql" {
		q = `SELECT DISTINCT cf_funding.user_id, sum(amount) as amount, time,  name, avatar
			FROM cf_funding
			LEFT JOIN users ON users.user_id = cf_funding.user_id
			WHERE project_id = ? AND
						del_block_id = 0
			GROUP BY cf_funding.user_id, time, name, avatar
			ORDER BY time DESC
			LIMIT 100`
	} else {
		q = `SELECT cf_funding.user_id, sum(amount) as amount, time,  name, avatar
			FROM cf_funding
			LEFT JOIN users ON users.user_id = cf_funding.user_id
			WHERE project_id = ? AND
						del_block_id = 0
			GROUP BY cf_funding.user_id
			ORDER BY time DESC
			LIMIT 100`
	}
	projectFunders, err := c.GetAll(q, 100, projectId)
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	for k, v := range projectFunders {
		t := time.Unix(utils.StrToInt64(v["time"]), 0)
		projectFunders[k]["time"] = t.Format(c.TimeFormat)
		if len(v["avatar"]) == 0 {
			projectFunders[k]["avatar"] = cfUrl + "static/img/noavatar.png"
		}
		if len(v["name"]) == 0 {
			projectFunders[k]["name"] = "Noname"
		}
	}

	// список комментов
	var projectComments []map[string]string
	if langId > 0 {
		projectComments, err = c.GetAll(`
				SELECT users.user_id, comment, time, name, avatar
				FROM cf_comments
				LEFT JOIN users ON users.user_id = cf_comments.user_id
				WHERE project_id = ? AND
							 lang_id = ?
				ORDER BY time DESC
				LIMIT 100
				`, 100, projectId, langId)
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		for k, v := range projectComments {
			t := time.Unix(utils.StrToInt64(v["time"]), 0)
			projectComments[k]["time"] = t.Format(c.TimeFormat)
			if len(v["avatar"]) == 0 {
				projectComments[k]["avatar"] = cfUrl + "static/img/noavatar.png"
			}
			if len(v["name"]) == 0 {
				projectComments[k]["name"] = "Noname"
			}
		}
	}
	// сколько всего комментов на каждом языке
	if c.ConfigIni["db_type"] == "postgresql" {
		q = `SELECT DISTINCT lang_id, count(id) as count FROM cf_comments WHERE project_id = ? GROUP BY lang_id`
	} else {
		q = `SELECT lang_id, count(id) as count FROM cf_comments WHERE project_id = ?`
	}
	langComments, err := c.GetMap(q, "lang_id", "count", projectId)
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	var projectCountComments int64
	for _, v := range langComments {
		projectCountComments += utils.StrToInt64(v)
	}

	cfLng, err := c.GetAllCfLng()

	// инфа об авторе проекта
	authorInfo, err := c.GetCfAuthorInfo(project["user_id"], cfUrl)

	// возможно наш юзер фундер
	project["funder"] = ""
	if c.SessUserId > 0 {
		project["funder"], err = c.Single("SELECT id FROM cf_funding WHERE project_id  =  ? AND user_id  =  ? AND del_block_id  =  0", projectId, c.SessUserId).String()
		if err != nil {
			return "", utils.ErrInfo(err)
		}
	}

	pagesArray := []string{"home", "news", "funders", "comments"}
	configCfPs := make(map[string][]string)
	if len(c.NodeConfig["cf_ps"]) > 0 {
		//{"1":["Credit card"],"2":["ik","MTS, Megafon, W1, Paxum"],"3":["pm","Perfect Money"]}
		err = json.Unmarshal([]byte(c.NodeConfig["cf_ps"]), &configCfPs)
		if err != nil {
			return "", utils.ErrInfo(err)
		}
	}

	// узнаем, какие платежные системы доступны данному проекту
	projectPs, err := c.OneRow("SELECT * FROM cf_projects_ps WHERE project_id  =  ?", projectId).String()
	if err != nil {
		return "", utils.ErrInfo(err)
	}

	// узнаем, не в блек-листе ли проект
	black, err := c.Single("SELECT project_id FROM cf_blacklist WHERE project_id  =  ?", projectId).Int64()
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	if black > 0 {
		return "", errors.New("Black project")
	}

	TemplateStr, err := makeTemplate("cf_page_preview", "cfPagePreview", &CfPagePreviewPage{
		Alert:                c.Alert,
		Lang:                 c.Lang,
		CountSignArr:         c.CountSignArr,
		ShowSignData:         c.ShowSignData,
		UserId:               c.SessUserId,
		TimeNow:              timeNow,
		TxType:               txType,
		TxTypeId:             txTypeId,
		SignData:             "",
		CfLng:                cfLng,
		CurrencyList:         c.CurrencyList,
		CfUrl:                cfUrl,
		ShowHeaders:          showHeaders,
		Page:                 page,
		CfCurrencyName:       cfCurrencyName,
		LangId:               langId,
		ProjectId:            projectId,
		BlurbImg:             blurbImg,
		HeadImg:              headImg,
		DescriptionImg:       descriptionImg,
		Picture:              picture,
		VideoType:            videoType,
		VideoUrlId:           videoUrlId,
		NewsImg:              newsImg,
		Links:                links,
		ImgBlank:             imgBlank,
		Project:              project,
		ProjectLang:          projectLang,
		ProjectFunding:       projectFunding,
		ProjectCountFunders:  projectCountFunders,
		ProjectFunders:       projectFunders,
		ProjectComments:      projectComments,
		LangComments:         langComments,
		ProjectCountComments: projectCountComments,
		AuthorInfo:           authorInfo,
		PagesArray:           pagesArray,
		ConfigCfPs:           configCfPs,
		ProjectPs:            projectPs,
		Black:                black})
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	return TemplateStr, nil
}
예제 #17
0
파일: new_miner.go 프로젝트: dzyk/dcoin-go
func (p *Parser) NewMinerFront() error {
	err := p.generalCheck()
	if err != nil {
		return p.ErrInfo(err)
	}
	// получим кол-во точек для face и profile
	exampleSpots_, err := p.DCDB.Single("SELECT example_spots FROM spots_compatibility").String()
	if err != nil {
		return p.ErrInfo(err)
	}

	exampleSpots := new(exampleSpots)
	err = json.Unmarshal([]byte(exampleSpots_), &exampleSpots)
	if err != nil {
		return p.ErrInfo(err)
	}

	if !utils.CheckInputData(p.TxMap["race"], "race") {
		return utils.ErrInfoFmt("race")
	}
	if !utils.CheckInputData(p.TxMap["country"], "country") {
		return utils.ErrInfoFmt("country")
	}
	if !utils.CheckInputData(p.TxMap["latitude"], "coordinate") {
		return utils.ErrInfoFmt("latitude")
	}
	if !utils.CheckInputData(p.TxMap["longitude"], "coordinate") {
		return utils.ErrInfoFmt("longitude")
	}
	if !utils.CheckInputData(p.TxMap["http_host"], "http_host") {
		return utils.ErrInfoFmt("http_host")
	}
	if p.BlockData == nil || p.BlockData.BlockId > 250900 {
		if !utils.CheckInputData(p.TxMap["tcp_host"], "tcp_host") {
			return utils.ErrInfoFmt("tcp_host")
		}
	}
	if !utils.CheckInputData_(p.TxMap["face_coords"], "coords", utils.IntToStr(len(exampleSpots.Face)-1)) {
		return utils.ErrInfoFmt("face_coords")
	}
	if !utils.CheckInputData_(p.TxMap["profile_coords"], "coords", utils.IntToStr(len(exampleSpots.Profile)-1)) {
		return utils.ErrInfoFmt("profile_coords")
	}
	if !utils.CheckInputData(p.TxMap["face_hash"], "photo_hash") {
		return utils.ErrInfoFmt("face_hash")
	}
	if !utils.CheckInputData(p.TxMap["profile_hash"], "photo_hash") {
		return utils.ErrInfoFmt("profile_hash")
	}
	if !utils.CheckInputData(p.TxMap["video_type"], "video_type") {
		return utils.ErrInfoFmt("video_type")
	}
	if !utils.CheckInputData(p.TxMap["video_url_id"], "video_url_id") {
		return utils.ErrInfoFmt("video_url_id %s", p.TxMap["video_url_id"])
	}
	if !utils.CheckInputData(p.TxMap["node_public_key"], "public_key") {
		return utils.ErrInfoFmt("node_public_key")
	}
	forSign := ""
	if p.BlockData != nil && p.BlockData.BlockId < 250900 {
		forSign = fmt.Sprintf("%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["race"], p.TxMap["country"], p.TxMap["latitude"], p.TxMap["longitude"], p.TxMap["http_host"], p.TxMap["face_hash"], p.TxMap["profile_hash"], p.TxMap["face_coords"], p.TxMap["profile_coords"], p.TxMap["video_type"], p.TxMap["video_url_id"], p.TxMap["node_public_key"])
	} else {
		forSign = fmt.Sprintf("%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["race"], p.TxMap["country"], p.TxMap["latitude"], p.TxMap["longitude"], p.TxMap["http_host"], p.TxMap["tcp_host"], p.TxMap["face_hash"], p.TxMap["profile_hash"], p.TxMap["face_coords"], p.TxMap["profile_coords"], p.TxMap["video_type"], p.TxMap["video_url_id"], p.TxMap["node_public_key"])

	}
	CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false)
	if err != nil {
		return p.ErrInfo(err)
	}
	if !CheckSignResult {
		return utils.ErrInfoFmt("incorrect sign")
	}

	// проверим, не кончились ли попытки стать майнером у данного юзера
	count, err := p.CountMinerAttempt(p.TxUserID, "user_voting")
	if count >= p.Variables.Int64["miner_votes_attempt"] {
		return utils.ErrInfoFmt("miner_votes_attempt")
	}
	if err != nil {
		return p.ErrInfo(err)
	}
	//  на всякий случай не даем начать нодовское, если идет юзерское голосование
	userVoting, err := p.DCDB.Single("SELECT id FROM votes_miners WHERE user_id = ? AND type = 'user_voting' AND votes_end = 0", p.TxUserID).String()
	if err != nil {
		return p.ErrInfo(err)
	}
	if len(userVoting) > 0 {
		return utils.ErrInfoFmt("existing $user_voting")
	}

	// проверим, не является ли юзер майнером и  не разжалованный ли это бывший майнер
	minerStatus, err := p.DCDB.Single("SELECT status FROM miners_data WHERE user_id = ? AND status IN ('miner','passive_miner','suspended_miner')", p.TxUserID).String()
	if err != nil {
		return p.ErrInfo(err)
	}
	if len(minerStatus) > 0 {
		return utils.ErrInfoFmt("incorrect miner status")
	}

	// разрешен 1 запрос за сутки
	err = p.limitRequest(p.Variables.Int64["limit_new_miner"], "new_miner", p.Variables.Int64["limit_new_miner_period"])
	if err != nil {
		return p.ErrInfo(err)
	}

	return nil
}
예제 #18
0
func (p *Parser) NewMaxOtherCurrenciesFront() error {

	err := p.generalCheck()
	if err != nil {
		return p.ErrInfo(err)
	}

	// является ли данный юзер майнером
	err = p.checkMiner(p.TxUserID)
	if err != nil {
		return p.ErrInfo(err)
	}

	nodePublicKey, err := p.GetNodePublicKey(p.TxUserID)
	if err != nil {
		return p.ErrInfo(err)
	}
	if len(nodePublicKey) == 0 {
		return p.ErrInfo("incorrect user_id")
	}

	totalCountCurrencies, err := p.GetCountCurrencies()
	if err != nil {
		return p.ErrInfo(err)
	}

	// проверим, верно ли указаны ID валют
	currencyList := make(map[string]int64)
	err = json.Unmarshal(p.TxMap["new_max_other_currencies"], &currencyList)
	if err != nil {
		return p.ErrInfo(err)
	}
	currencyIdsSql := ""
	var countCurrency int64
	for currencyId, count := range currencyList {
		if !utils.CheckInputData(currencyId, "int") {
			return p.ErrInfo("currencyId")
		}
		currencyIdsSql += currencyId + ","
		countCurrency++
		if count > totalCountCurrencies {
			return p.ErrInfo("count > totalCountCurrencies")
		}
	}
	currencyIdsSql = currencyIdsSql[0 : len(currencyIdsSql)-1]
	if countCurrency == 0 {
		return p.ErrInfo("countCurrency")
	}
	count, err := p.Single("SELECT count(id) FROM currency WHERE id IN (" + currencyIdsSql + ")").Int64()
	if err != nil {
		return p.ErrInfo(err)
	}
	if count != countCurrency {
		return p.ErrInfo("count != countCurrency")
	}

	forSign := fmt.Sprintf("%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["new_max_other_currencies"])
	CheckSignResult, err := utils.CheckSign([][]byte{nodePublicKey}, forSign, p.TxMap["sign"], true)
	if err != nil {
		return p.ErrInfo(err)
	}
	if !CheckSignResult {
		return p.ErrInfo("incorrect sign")
	}

	// проверим, прошло ли 2 недели с момента последнего обновления
	pctTime, err := p.Single("SELECT max(time) FROM max_other_currencies_time").Int64()
	if err != nil {
		return p.ErrInfo(err)
	}
	if p.TxTime-pctTime <= p.Variables.Int64["new_max_other_currencies"] {
		return p.ErrInfo("14 day error")
	}

	// берем все голоса
	maxOtherCurrenciesVotes := make(map[int64][]map[int64]int64)
	rows, err := p.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 {
		return p.ErrInfo(err)
	}
	defer rows.Close()
	for rows.Next() {
		var currency_id, count, votes int64
		err = rows.Scan(&currency_id, &count, &votes)
		if err != nil {
			return p.ErrInfo(err)
		}
		maxOtherCurrenciesVotes[currency_id] = append(maxOtherCurrenciesVotes[currency_id], map[int64]int64{count: votes})
		//fmt.Println("currency_id", currency_id)
	}
	//fmt.Println("maxOtherCurrenciesVotes", maxOtherCurrenciesVotes)

	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)
	if err != nil {
		return p.ErrInfo(err)
	}
	if string(p.TxMap["new_max_other_currencies"]) != string(jsonData) {
		return p.ErrInfo("p.TxMap[new_max_other_currencies] != jsonData " + string(p.TxMap["new_max_other_currencies"]) + "!=" + string(jsonData))
	}

	return nil
}
예제 #19
0
/**
Обработка данных (блоков или транзакций), пришедших с гейта. Только проверка.
*/
func (p *Parser) ParseDataGate(onlyTx bool) error {

	var err error
	p.dataPre()
	p.TxIds = []string{}

	p.Variables, err = p.GetAllVariables()
	if err != nil {
		return utils.ErrInfo(err)
	}

	transactionBinaryData := p.BinaryData
	var transactionBinaryDataFull []byte

	// если это транзакции (type>0), а не блок (type==0)
	if p.dataType > 0 {

		// проверим, есть ли такой тип тр-ий
		if len(consts.TxTypes[p.dataType]) == 0 {
			return p.ErrInfo("Incorrect tx type " + utils.IntToStr(p.dataType))
		}

		log.Debug("p.dataType %v", p.dataType)
		transactionBinaryData = append(utils.DecToBin(int64(p.dataType), 1), transactionBinaryData...)
		transactionBinaryDataFull = transactionBinaryData

		// нет ли хэша этой тр-ии у нас в БД?
		err = p.CheckLogTx(transactionBinaryDataFull)
		if err != nil {
			return p.ErrInfo(err)
		}

		p.TxHash = utils.Md5(transactionBinaryData)

		// преобразуем бинарные данные транзакции в массив
		p.TxSlice, err = p.ParseTransaction(&transactionBinaryData)
		if err != nil {
			return p.ErrInfo(err)
		}
		log.Debug("p.TxSlice", p.TxSlice)
		if len(p.TxSlice) < 3 {
			return p.ErrInfo(errors.New("len(p.TxSlice) < 3"))
		}

		// время транзакции может быть немного больше, чем время на ноде.
		// у нода может быть просто не настроено время.
		// время транзакции используется только для борьбы с атаками вчерашними транзакциями.
		// А т.к. мы храним хэши в log_transaction за 36 часов, то боятся нечего.
		curTime := utils.Time()
		if utils.BytesToInt64(p.TxSlice[2])-consts.MAX_TX_FORW > curTime || utils.BytesToInt64(p.TxSlice[2]) < curTime-consts.MAX_TX_BACK {
			return p.ErrInfo(errors.New("incorrect tx time"))
		}
		// $this->transaction_array[3] могут подсунуть пустой
		if !utils.CheckInputData(p.TxSlice[3], "bigint") {
			return p.ErrInfo(errors.New("incorrect user id"))
		}
	}

	// если это блок
	if p.dataType == 0 {

		txCounter := make(map[int64]int64)

		// если есть $only_tx=true, то значит идет восстановление уже проверенного блока и заголовок не требуется
		if !onlyTx {
			err = p.ParseBlock()
			if err != nil {
				return p.ErrInfo(err)
			}

			// проверим данные, указанные в заголовке блока
			err = p.CheckBlockHeader()
			if err != nil {
				return p.ErrInfo(err)
			}
		}
		log.Debug("onlyTx", onlyTx)

		// если в ходе проверки тр-ий возникает ошибка, то вызываем откатчик всех занесенных тр-ий. Эта переменная для него
		p.fullTxBinaryData = p.BinaryData
		var txForRollbackTo []byte
		if len(p.BinaryData) > 0 {
			for {
				transactionSize := utils.DecodeLength(&p.BinaryData)
				if len(p.BinaryData) == 0 {
					return utils.ErrInfo(fmt.Errorf("empty BinaryData"))
				}

				// отчекрыжим одну транзакцию от списка транзакций
				transactionBinaryData := utils.BytesShift(&p.BinaryData, transactionSize)
				transactionBinaryDataFull = transactionBinaryData

				// добавляем взятую тр-ию в набор тр-ий для RollbackTo, в котором пойдем в обратном порядке
				txForRollbackTo = append(txForRollbackTo, utils.EncodeLengthPlusData(transactionBinaryData)...)

				// нет ли хэша этой тр-ии у нас в БД?
				err = p.CheckLogTx(transactionBinaryDataFull)
				if err != nil {
					p.RollbackTo(txForRollbackTo, true, false)
					return p.ErrInfo(err)
				}

				p.TxHash = utils.Md5(transactionBinaryData)
				p.TxSlice, err = p.ParseTransaction(&transactionBinaryData)
				log.Debug("p.TxSlice %s", p.TxSlice)
				if err != nil {
					p.RollbackTo(txForRollbackTo, true, false)
					return p.ErrInfo(err)
				}

				var userId int64
				// txSlice[3] могут подсунуть пустой
				if len(p.TxSlice) > 3 {
					if !utils.CheckInputData(p.TxSlice[3], "int64") {
						return utils.ErrInfo(fmt.Errorf("empty user_id"))
					} else {
						userId = utils.BytesToInt64(p.TxSlice[3])
					}
				} else {
					return utils.ErrInfo(fmt.Errorf("empty user_id"))
				}

				// считаем по каждому юзеру, сколько в блоке от него транзакций
				txCounter[userId]++

				// чтобы 1 юзер не смог прислать дос-блок размером в 10гб, который заполнит своими же транзакциями
				if txCounter[userId] > p.Variables.Int64["max_block_user_transactions"] {
					p.RollbackTo(txForRollbackTo, true, false)
					return utils.ErrInfo(fmt.Errorf("max_block_user_transactions"))
				}

				// проверим, есть ли такой тип тр-ий
				_, ok := consts.TxTypes[utils.BytesToInt(p.TxSlice[1])]
				if !ok {
					return utils.ErrInfo(fmt.Errorf("nonexistent type"))
				}

				p.TxMap = map[string][]byte{}

				// для статы
				p.TxIds = append(p.TxIds, string(p.TxSlice[1]))

				MethodName := consts.TxTypes[utils.BytesToInt(p.TxSlice[1])]
				log.Debug("MethodName", MethodName+"Init")
				err_ := utils.CallMethod(p, MethodName+"Init")
				if _, ok := err_.(error); ok {
					log.Debug("error: %v", err)
					p.RollbackTo(txForRollbackTo, true, true)
					return utils.ErrInfo(err_.(error))
				}

				log.Debug("MethodName", MethodName+"Front")
				err_ = utils.CallMethod(p, MethodName+"Front")
				if _, ok := err_.(error); ok {
					log.Debug("error: %v", err)
					p.RollbackTo(txForRollbackTo, true, true)
					return utils.ErrInfo(err_.(error))
				}

				// пишем хэш тр-ии в лог
				err = p.InsertInLogTx(transactionBinaryDataFull, utils.BytesToInt64(p.TxMap["time"]))
				if err != nil {
					return utils.ErrInfo(err)
				}

				if len(p.BinaryData) == 0 {
					break
				}
			}
		}
	} else {

		// Оперативные транзакции
		MethodName := consts.TxTypes[p.dataType]
		log.Debug("MethodName", MethodName+"Init")
		err_ := utils.CallMethod(p, MethodName+"Init")
		if _, ok := err_.(error); ok {
			return utils.ErrInfo(err_.(error))
		}

		log.Debug("MethodName", MethodName+"Front")
		err_ = utils.CallMethod(p, MethodName+"Front")
		if _, ok := err_.(error); ok {
			return utils.ErrInfo(err_.(error))
		}

		// пишем хэш тр-ии в лог
		err = p.InsertInLogTx(transactionBinaryDataFull, utils.BytesToInt64(p.TxMap["time"]))
		if err != nil {
			return utils.ErrInfo(err)
		}
	}

	return nil
}
예제 #20
0
func (p *Parser) CfProjectDataFront() error {

	err := p.generalCheck()
	if err != nil {
		return p.ErrInfo(err)
	}

	verifyData := map[string]string{"project_id": "int", "lang_id": "tinyint"}
	err = p.CheckInputData(verifyData)
	if err != nil {
		return p.ErrInfo(err)
	}
	if !utils.CheckInputData(p.TxMaps.String["blurb_img"], "img_url") && p.TxMaps.String["blurb_img"] != "0" {
		return fmt.Errorf("incorrect blurb_img")
	}
	if !utils.CheckInputData(p.TxMaps.String["head_img"], "img_url") && p.TxMaps.String["head_img"] != "0" {
		return fmt.Errorf("incorrect head_img")
	}
	if !utils.CheckInputData(p.TxMaps.String["description_img"], "img_url") && p.TxMaps.String["description_img"] != "0" {
		return fmt.Errorf("incorrect description_img")
	}
	if !utils.CheckInputData(p.TxMaps.String["picture"], "img_url") && p.TxMaps.String["picture"] != "0" {
		return fmt.Errorf("incorrect picture")
	}
	if !utils.CheckInputData(p.TxMaps.String["video_type"], "video_type") && p.TxMaps.String["video_type"] != "0" {
		return fmt.Errorf("incorrect blurb_img")
	}
	if !utils.CheckInputData(p.TxMaps.String["video_url_id"], "video_url_id") && p.TxMaps.String["video_url_id"] != "0" {
		return fmt.Errorf("incorrect video_url_id")
	}
	if !utils.CheckInputData(p.TxMaps.String["news_img"], "img_url") && p.TxMaps.String["news_img"] != "0" {
		return fmt.Errorf("incorrect news_img")
	}
	if !utils.CheckInputData(p.TxMaps.String["links"], "cf_links") && p.TxMaps.String["links"] != "0" {
		return fmt.Errorf("incorrect links")
	}

	// для подписи
	if p.BlockData != nil && p.BlockData.BlockId < 134261 {
		p.TxMap["hide"] = []byte(`0`)
	} else {
		if !utils.CheckInputData(p.TxMap["hide"], "boolean") {
			return fmt.Errorf("incorrect hide")
		}
	}

	// является ли юзер владельцем данного проекта и есть ли вообще такой проект
	projectUserId, err := p.Single("SELECT user_id FROM cf_projects WHERE user_id  =  ? AND id  =  ?", p.TxUserID, p.TxMaps.Int64["project_id"]).Int64()
	if err != nil {
		return p.ErrInfo(err)
	}
	if projectUserId == 0 {
		return fmt.Errorf("incorrect project_user_id")
	}

	var forSign string
	if p.BlockData != nil && p.BlockData.BlockId < 134261 {
		forSign = fmt.Sprintf("%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["project_id"], p.TxMap["lang_id"], p.TxMap["blurb_img"], p.TxMap["head_img"], p.TxMap["description_img"], p.TxMap["picture"], p.TxMap["video_type"], p.TxMap["video_url_id"], p.TxMap["news_img"], p.TxMap["links"])
	} else {
		forSign = fmt.Sprintf("%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["project_id"], p.TxMap["lang_id"], p.TxMap["blurb_img"], p.TxMap["head_img"], p.TxMap["description_img"], p.TxMap["picture"], p.TxMap["video_type"], p.TxMap["video_url_id"], p.TxMap["news_img"], p.TxMap["links"], p.TxMap["hide"])

	}

	CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false)
	if err != nil {
		return p.ErrInfo(err)
	}
	if !CheckSignResult {
		return p.ErrInfo("incorrect sign")
	}

	err = p.limitRequest(consts.LIMIT_CF_PROJECT_DATA, "cf_project_data", consts.LIMIT_CF_PROJECT_DATA_PERIOD)
	if err != nil {
		return p.ErrInfo(err)
	}
	return nil
}
예제 #21
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
}
예제 #22
0
파일: miners_map.go 프로젝트: dzyk/dcoin-go
func (c *Controller) MinersMap() (string, error) {

	if c.SessRestricted != 0 {
		return "", utils.ErrInfo(errors.New("Permission denied"))
	}

	c.r.ParseForm()

	log.Debug("min_amount:", c.r.FormValue("min_amount"))
	minAmount := utils.StrToFloat64(c.r.FormValue("min_amount"))
	log.Debug("minAmount:", minAmount)
	if !utils.CheckInputData(c.r.FormValue("min_amount"), "amount") {
		return "", errors.New("Incorrect min_amount")
	}
	currencyId := utils.StrToInt64(c.r.FormValue("currency_id"))
	if !utils.CheckInputData(c.r.FormValue("currency_id"), "currency_id") {
		return "", errors.New("Incorrect currency_id")
	}
	paymentSystemId := utils.StrToInt64(c.r.FormValue("payment_system_id"))
	if !utils.CheckInputData(c.r.FormValue("payment_system_id"), "int") {
		return "", errors.New("Incorrect payment_system_id")
	}

	maxPromisedAmounts, err := c.Single("SELECT amount FROM max_promised_amounts WHERE currency_id  =  ? ORDER BY time DESC", currencyId).Float64()
	if err != nil {
		return "", utils.ErrInfo(err)
	}

	addSql := ""
	if paymentSystemId > 0 {
		addSql = fmt.Sprintf(` (ps1 = %d OR ps2 = %d OR ps3 = %d OR ps4 = %d OR ps5 = %d) AND`, paymentSystemId, paymentSystemId, paymentSystemId, paymentSystemId, paymentSystemId)
	}

	rows, err := c.Query(c.FormatQuery(`
			SELECT  amount,
						 latitude,
						 longitude,
						 promised_amount.user_id
			FROM promised_amount
			LEFT JOIN miners_data ON miners_data.user_id = promised_amount.user_id
			WHERE  promised_amount.status = 'mining' AND
						 currency_id = ? AND
						  `+addSql+`
						  promised_amount.user_id != ? AND
						  del_block_id = 0
	`), currencyId, c.SessUserId)
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	result := ""
	defer rows.Close()
	for rows.Next() {
		var amount float64
		var latitude, longitude string
		var user_id int64
		err = rows.Scan(&amount, &latitude, &longitude, &user_id)
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		repaid, err := c.Single("SELECT amount FROM promised_amount WHERE status  =  'repaid' AND currency_id  =  ? AND user_id  =  ? AND del_block_id  =  0", currencyId, user_id).Float64()
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		var returnAmount float64
		if repaid+amount < maxPromisedAmounts {
			returnAmount = amount
		} else {
			returnAmount = maxPromisedAmounts - repaid
		}
		if returnAmount <= 0 {
			continue
		}
		result += fmt.Sprintf(`{"user_id": %v, "amount": %v, "longitude": %v, "latitude": %v},`, user_id, returnAmount, longitude, latitude)
	}
	if len(result) > 0 {
		result = result[:len(result)-1]
	}
	log.Debug(result)
	result = `{ "info": [` + result + `]}`
	return result, nil
}
예제 #23
0
/**
 * Занесение данных из блока в БД
 * используется только в testblock_is_ready
 */
func (p *Parser) ParseDataFront() error {

	p.TxIds = []string{}
	p.dataPre()
	if p.dataType == 0 {
		// инфа о предыдущем блоке (т.е. последнем занесенном)
		err := p.GetInfoBlock()
		if err != nil {
			return p.ErrInfo(err)
		}

		utils.WriteSelectiveLog("DELETE FROM transactions WHERE used=1")
		affect, err := p.ExecSqlGetAffect("DELETE FROM transactions WHERE used = 1")
		if err != nil {
			utils.WriteSelectiveLog(err)
			return p.ErrInfo(err)
		}
		utils.WriteSelectiveLog("affect: " + utils.Int64ToStr(affect))

		// разбор блока
		err = p.ParseBlock()
		if err != nil {
			return utils.ErrInfo(err)
		}

		p.Variables, err = p.GetAllVariables()
		if err != nil {
			return utils.ErrInfo(err)
		}
		//меркель рут нужен для updblockinfo()
		p.MrklRoot, err = utils.GetMrklroot(p.BinaryData, p.Variables, false)
		if err != nil {
			return utils.ErrInfo(err)
		}
		if len(p.BinaryData) > 0 {
			for {
				transactionSize := utils.DecodeLength(&p.BinaryData)
				if len(p.BinaryData) == 0 {
					return utils.ErrInfo(fmt.Errorf("empty BinaryData"))
				}
				// отчекрыжим одну транзакцию от списка транзакций
				transactionBinaryData := utils.BytesShift(&p.BinaryData, transactionSize)
				transactionBinaryDataFull := transactionBinaryData

				p.TxHash = utils.Md5(transactionBinaryData)
				log.Debug("p.TxHash", p.TxHash)
				p.TxSlice, err = p.ParseTransaction(&transactionBinaryData)
				log.Debug("p.TxSlice", p.TxSlice)
				if err != nil {
					return utils.ErrInfo(err)
				}

				// txSlice[3] могут подсунуть пустой
				if len(p.TxSlice) > 3 {
					if !utils.CheckInputData(p.TxSlice[3], "int64") {
						return utils.ErrInfo(fmt.Errorf("empty user_id"))
					}
				} else {
					return utils.ErrInfo(fmt.Errorf("empty user_id"))
				}

				// проверим, есть ли такой тип тр-ий
				_, ok := consts.TxTypes[utils.BytesToInt(p.TxSlice[1])]
				if !ok {
					return utils.ErrInfo(fmt.Errorf("nonexistent type"))
				}

				p.TxMap = map[string][]byte{}

				// для статы
				p.TxIds = append(p.TxIds, string(p.TxSlice[1]))

				MethodName := consts.TxTypes[utils.BytesToInt(p.TxSlice[1])]
				log.Debug("MethodName", MethodName+"Init")
				err_ := utils.CallMethod(p, MethodName+"Init")
				if _, ok := err_.(error); ok {
					log.Debug("error: %v", err)
					return utils.ErrInfo(err_.(error))
				}

				log.Debug("MethodName", MethodName)
				err_ = utils.CallMethod(p, MethodName)
				if _, ok := err_.(error); ok {
					log.Debug("error: %v", err)
					return utils.ErrInfo(err_.(error))
				}

				utils.WriteSelectiveLog("UPDATE transactions SET used=1 WHERE hex(hash) = " + string(utils.Md5(transactionBinaryDataFull)))
				affect, err := p.ExecSqlGetAffect("UPDATE transactions SET used=1 WHERE hex(hash) = ?", utils.Md5(transactionBinaryDataFull))
				if err != nil {
					utils.WriteSelectiveLog(err)
					return utils.ErrInfo(err)
				}
				utils.WriteSelectiveLog("affect: " + utils.Int64ToStr(affect))

				// даем юзеру понять, что его тр-ия попала в блок
				err = p.ExecSql("UPDATE transactions_status SET block_id = ? WHERE hex(hash) = ?", p.BlockData.BlockId, utils.Md5(transactionBinaryDataFull))
				if err != nil {
					return utils.ErrInfo(err)
				}

				if len(p.BinaryData) == 0 {
					break
				}
			}
		}

		p.UpdBlockInfo()
		p.InsertIntoBlockchain()
	} else {
		return utils.ErrInfo(fmt.Errorf("incorrect type"))
	}

	return nil
}
예제 #24
0
func (c *Controller) GetSellerData() (string, error) {

	c.r.ParseForm()

	getUserId := utils.StrToInt64(c.r.FormValue("user_id"))
	if !utils.CheckInputData(getUserId, "int") {
		return `{"result":"incorrect userId"}`, nil
	}
	currencyId := utils.StrToInt64(c.r.FormValue("currency_id"))
	if !utils.CheckInputData(currencyId, "currency_id") {
		return `{"result":"incorrect currency_id"}`, nil
	}

	arbitrationTrustList, err := c.GetList("SELECT arbitrator_user_id FROM arbitration_trust_list WHERE user_id  =  ?", getUserId).Int64()
	if err != nil {
		return "", utils.ErrInfo(err)
	}

	/*
	 * Статистика по продавцу
	 * */
	// оборот всего
	sellerTurnover, err := c.Single("SELECT sum(amount) FROM orders WHERE seller  =  ? AND currency_id  =  ?", getUserId, currencyId).Float64()
	if err != nil {
		return "", utils.ErrInfo(err)
	}

	// оборот за месяц
	sellerTurnoverM, err := c.Single("SELECT sum(amount) FROM orders WHERE seller  =  ? AND time > ? AND currency_id  =  ?", getUserId, time.Now().Unix()-3600*24*30, currencyId).Float64()
	if err != nil {
		return "", utils.ErrInfo(err)
	}

	// Кол-во покупателей за последний месяц
	var q string
	if c.ConfigIni["db_type"] == "postgresql" {
		q = `SELECT count(id) FROM ( SELECT DISTINCT id FROM orders WHERE seller  =  ? AND time > ? AND currency_id  =  ? GROUP BY buyer, id ) as t1`
	} else {
		q = `SELECT count(id) FROM ( SELECT id FROM orders WHERE seller  =  ? AND time > ? AND currency_id  =  ? GROUP BY buyer ) as t1`
	}
	buyersCountM, err := c.Single(q, getUserId, currencyId, time.Now().Unix()-3600*24*30).Int64()
	if err != nil {
		return "", utils.ErrInfo(err)
	}

	// Кол-во покупателей-майнеров за последний месяц
	if c.ConfigIni["db_type"] == "postgresql" {
		q = `SELECT count(id)
			FROM (
				SELECT DISTINCT orders.id
				FROM orders
				LEFT JOIN miners_data ON miners_data.user_id =  orders.buyer
				WHERE seller = ? AND
							 orders.time > ? AND
							 orders.currency_id =  ? AND
							 miner_id > 0
				GROUP BY buyer, orders.id
			) as t1`
	} else {
		q = `SELECT count(id)
			FROM (
				SELECT orders.id
				FROM orders
				LEFT JOIN miners_data ON miners_data.user_id =  orders.buyer
				WHERE seller = ? AND
							 orders.time > ? AND
							 orders.currency_id =  ? AND
							 miner_id > 0
				GROUP BY buyer
			) as t1`
	}
	buyersMinersCountM, err := c.Single(q, getUserId, time.Now().Unix()-3600*24*30, currencyId).Int64()
	if err != nil {
		return "", utils.ErrInfo(err)
	}

	// Кол-во покупателей всего
	if c.ConfigIni["db_type"] == "postgresql" {
		q = `SELECT count(id) FROM ( SELECT DISTINCT id FROM orders WHERE seller  =  ? AND currency_id  =  ? GROUP BY buyer, id ) as t1`
	} else {
		q = `SELECT count(id) FROM ( SELECT id FROM orders WHERE seller  =  ? AND currency_id  =  ? GROUP BY buyer ) as t1`
	}
	buyersCount, err := c.Single(q, getUserId, currencyId).Int64()
	if err != nil {
		return "", utils.ErrInfo(err)
	}

	// Кол-во покупателей-майнеров всего
	if c.ConfigIni["db_type"] == "postgresql" {
		q = `SELECT count(id)
			FROM (
				SELECT DISTINCT orders.id
				FROM orders
				LEFT JOIN miners_data ON miners_data.user_id =  orders.buyer
				WHERE seller = ? AND
							 orders.currency_id = ? AND
							 miner_id > 0
				GROUP BY buyer, orders.id
			) as t1`
	} else {
		q = `SELECT count(id)
			FROM (
				SELECT orders.id
				FROM orders
				LEFT JOIN miners_data ON miners_data.user_id =  orders.buyer
				WHERE seller = ? AND
							 orders.currency_id = ? AND
							 miner_id > 0
				GROUP BY buyer
			) as t1`
	}
	buyersMinersCount, err := c.Single(q, getUserId, currencyId).Int64()
	if err != nil {
		return "", utils.ErrInfo(err)
	}

	// Заморожено для манибека
	holdAmount, err := c.Single(`
		SELECT sum(hold_back_amount)
		FROM orders
		LEFT JOIN miners_data ON miners_data.user_id =  orders.buyer
		WHERE seller = ? AND
					 orders.currency_id = ? AND
					 miner_id > 0
		GROUP BY buyer
	`, getUserId, currencyId).Float64()
	if err != nil {
		return "", utils.ErrInfo(err)
	}

	// Холдбек % на 30 дней
	sellerData, err := c.OneRow("SELECT seller_hold_back_pct, arbitration_days_refund FROM users WHERE user_id  =  ?", getUserId).String()
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	sellerHoldBackPct := utils.StrToFloat64(sellerData["seller_hold_back_pct"])
	arbitrationDaysRefund := utils.StrToInt64(sellerData["arbitrationDaysRefund"])
	buyersCount = buyersCount - buyersMinersCount
	buyersCountM = buyersCountM - buyersMinersCountM

	rez := selleData{Trust_list: arbitrationTrustList, Seller_hold_back_pct: sellerHoldBackPct, Arbitration_days_refund: arbitrationDaysRefund, Buyers_miners_count_m: buyersMinersCountM, Buyers_miners_count: buyersMinersCount, Buyers_count: buyersCount, Buyers_count_m: buyersCountM, Seller_turnover_m: sellerTurnoverM, Seller_turnover: sellerTurnover, Hold_amount: holdAmount}
	log.Debug("%v", rez)
	log.Debug("%v", arbitrationTrustList)
	result, err := json.Marshal(rez)
	if err != nil {
		log.Error("%v", err)
		return "", utils.ErrInfo(err)
	}
	log.Debug(string(result))

	return string(result), nil
}
예제 #25
0
/**
фронт. проверка + занесение данных из блока в таблицы и info_block
*/
func (p *Parser) ParseDataFull() error {

	p.TxIds = []string{}
	p.dataPre()
	if p.dataType != 0 { // парсим только блоки
		return utils.ErrInfo(fmt.Errorf("incorrect dataType"))
	}
	var err error

	p.Variables, err = p.GetAllVariables()
	if err != nil {
		return utils.ErrInfo(err)
	}

	//if len(p.BinaryData) > 500000 {
	//	ioutil.WriteFile("block-"+string(utils.DSha256(p.BinaryData)), p.BinaryData, 0644)
	//}

	err = p.ParseBlock()
	if err != nil {
		return utils.ErrInfo(err)
	}

	// проверим данные, указанные в заголовке блока
	err = p.CheckBlockHeader()
	if err != nil {
		return utils.ErrInfo(err)
	}

	utils.WriteSelectiveLog("DELETE FROM transactions WHERE used = 1")
	afect, err := p.ExecSqlGetAffect("DELETE FROM transactions WHERE used = 1")
	if err != nil {
		utils.WriteSelectiveLog(err)
		return utils.ErrInfo(err)
	}
	utils.WriteSelectiveLog("afect: " + utils.Int64ToStr(afect))

	txCounter := make(map[int64]int64)
	p.fullTxBinaryData = p.BinaryData
	var txForRollbackTo []byte
	if len(p.BinaryData) > 0 {
		for {
			// обработка тр-ий может занять много времени, нужно отметиться
			p.UpdDaemonTime(p.GoroutineName)
			p.halfRollback = false
			log.Debug("&p.BinaryData", p.BinaryData)
			transactionSize := utils.DecodeLength(&p.BinaryData)
			if len(p.BinaryData) == 0 {
				return utils.ErrInfo(fmt.Errorf("empty BinaryData"))
			}

			// отчекрыжим одну транзакцию от списка транзакций
			//log.Debug("++p.BinaryData=%x\n", p.BinaryData)
			//log.Debug("transactionSize", transactionSize)
			transactionBinaryData := utils.BytesShift(&p.BinaryData, transactionSize)
			transactionBinaryDataFull := transactionBinaryData
			//ioutil.WriteFile("/tmp/dctx", transactionBinaryDataFull, 0644)
			//ioutil.WriteFile("/tmp/dctxhash", utils.Md5(transactionBinaryDataFull), 0644)
			// добавляем взятую тр-ию в набор тр-ий для RollbackTo, в котором пойдем в обратном порядке
			txForRollbackTo = append(txForRollbackTo, utils.EncodeLengthPlusData(transactionBinaryData)...)
			//log.Debug("transactionBinaryData: %x\n", transactionBinaryData)
			//log.Debug("txForRollbackTo: %x\n", txForRollbackTo)

			err = p.CheckLogTx(transactionBinaryDataFull)
			if err != nil {
				p.RollbackTo(txForRollbackTo, true, false)
				return utils.ErrInfo(err)
			}

			utils.WriteSelectiveLog("UPDATE transactions SET used=1 WHERE hex(hash) = " + string(utils.Md5(transactionBinaryDataFull)))
			affect, err := p.ExecSqlGetAffect("UPDATE transactions SET used=1 WHERE hex(hash) = ?", utils.Md5(transactionBinaryDataFull))
			if err != nil {
				utils.WriteSelectiveLog(err)
				utils.WriteSelectiveLog("RollbackTo")
				p.RollbackTo(txForRollbackTo, true, false)
				return utils.ErrInfo(err)
			}
			utils.WriteSelectiveLog("affect: " + utils.Int64ToStr(affect))
			//log.Debug("transactionBinaryData", transactionBinaryData)
			p.TxHash = utils.Md5(transactionBinaryData)
			log.Debug("p.TxHash %s", p.TxHash)
			p.TxSlice, err = p.ParseTransaction(&transactionBinaryData)
			log.Debug("p.TxSlice %v", p.TxSlice)
			if err != nil {
				p.RollbackTo(txForRollbackTo, true, false)
				return err
			}

			if p.BlockData.BlockId > 1 {
				var userId int64
				// txSlice[3] могут подсунуть пустой
				if len(p.TxSlice) > 3 {
					if !utils.CheckInputData(p.TxSlice[3], "int64") {
						return utils.ErrInfo(fmt.Errorf("empty user_id"))
					} else {
						userId = utils.BytesToInt64(p.TxSlice[3])
					}
				} else {
					return utils.ErrInfo(fmt.Errorf("empty user_id"))
				}

				// считаем по каждому юзеру, сколько в блоке от него транзакций
				txCounter[userId]++

				// чтобы 1 юзер не смог прислать дос-блок размером в 10гб, который заполнит своими же транзакциями
				if txCounter[userId] > p.Variables.Int64["max_block_user_transactions"] {
					p.RollbackTo(txForRollbackTo, true, false)
					return utils.ErrInfo(fmt.Errorf("max_block_user_transactions"))
				}
			}

			// время в транзакции не может быть больше, чем на MAX_TX_FORW сек времени блока
			// и  время в транзакции не может быть меньше времени блока -24ч.
			if utils.BytesToInt64(p.TxSlice[2])-consts.MAX_TX_FORW > p.BlockData.Time || utils.BytesToInt64(p.TxSlice[2]) < p.BlockData.Time-consts.MAX_TX_BACK {
				p.RollbackTo(txForRollbackTo, true, false)
				return utils.ErrInfo(fmt.Errorf("incorrect transaction time"))
			}

			// проверим, есть ли такой тип тр-ий
			_, ok := consts.TxTypes[utils.BytesToInt(p.TxSlice[1])]
			if !ok {
				return utils.ErrInfo(fmt.Errorf("nonexistent type"))
			}

			p.TxMap = map[string][]byte{}

			// для статы
			p.TxIds = append(p.TxIds, string(p.TxSlice[1]))

			MethodName := consts.TxTypes[utils.BytesToInt(p.TxSlice[1])]
			log.Debug("MethodName", MethodName+"Init")
			err_ := utils.CallMethod(p, MethodName+"Init")
			if _, ok := err_.(error); ok {
				log.Error("error: %v", err)
				return utils.ErrInfo(err_.(error))
			}

			log.Debug("MethodName", MethodName+"Front")
			err_ = utils.CallMethod(p, MethodName+"Front")
			if _, ok := err_.(error); ok {
				log.Error("error: %v", err_)
				p.RollbackTo(txForRollbackTo, true, false)
				return utils.ErrInfo(err_.(error))
			}

			log.Debug("MethodName", MethodName)
			err_ = utils.CallMethod(p, MethodName)
			if _, ok := err_.(error); ok {
				log.Error("error: %v", err)
				return utils.ErrInfo(err_.(error))
			}

			// даем юзеру понять, что его тр-ия попала в блок
			p.ExecSql("UPDATE transactions_status SET block_id = ? WHERE hex(hash) = ?", p.BlockData.BlockId, utils.Md5(transactionBinaryDataFull))

			// Тут было time(). А значит если бы в цепочке блоков были блоки в которых были бы одинаковые хэши тр-ий, то ParseDataFull вернул бы error
			err = p.InsertInLogTx(transactionBinaryDataFull, utils.BytesToInt64(p.TxMap["time"]))
			if err != nil {
				return utils.ErrInfo(err)
			}

			if len(p.BinaryData) == 0 {
				break
			}
		}
	}

	p.UpdBlockInfo()

	return nil
}
예제 #26
0
파일: cf_comment.go 프로젝트: dzyk/dcoin-go
func (p *Parser) CfCommentFront() error {

	err := p.generalCheck()
	if err != nil {
		return p.ErrInfo(err)
	}

	verifyData := map[string]string{"project_id": "int", "comment": "cf_comment"}
	err = p.CheckInputData(verifyData)
	if err != nil {
		return p.ErrInfo(err)
	}

	if !utils.CheckInputData(p.TxMaps.Int64["lang_id"], "tinyint") || p.TxMaps.Int64["lang_id"] <= 0 {
		return fmt.Errorf("incorrect lang_id")
	}

	var txTime int64
	if p.BlockData != nil {
		txTime = p.BlockData.Time
	} else { // голая тр-ия с запасом 30 сек на время генерации блока. Т.к. при попадинии в блок время будет уже другим
		txTime = time.Now().Unix() - 30
	}

	// автор проекта может писать по 1 комменту за каждую языковую версию
	author, err := p.Single("SELECT id FROM cf_projects WHERE user_id  =  ? AND id  =  ?", p.TxUserID, p.TxMaps.Int64["project_id"]).Int64()
	if err != nil {
		return p.ErrInfo(err)
	}
	addSql := ""
	if author > 0 {
		addSql = " AND lang_id = " + utils.Int64ToStr(p.TxMaps.Int64["lang_id"])
	} else {
		addSql = ""
	}

	// проверим, есть ли у данного юзера другие комменты за данный проект
	commentTime, err := p.Single("SELECT max(time) FROM cf_comments WHERE user_id  =  ? AND project_id  =  ? "+addSql, p.TxUserID, p.TxMaps.Int64["project_id"]).Int64()
	if err != nil {
		return p.ErrInfo(err)
	}

	// в 1 проект можно писать только 1 комммент в сутки
	if txTime-commentTime < consts.LIMIT_TIME_COMMENTS_CF_PROJECT {
		return p.ErrInfo("comment_time")
	}

	// финансировал ли данный юзер этот проект
	funder, err := p.Single(" SELECT id FROM cf_funding WHERE user_id  =  ? AND project_id  =  ?", p.TxUserID, p.TxMaps.Int64["project_id"]).Int64()
	if err != nil {
		return p.ErrInfo(err)
	}
	if funder == 0 {
		//  или может быть он его автор
		author, err := p.Single("SELECT id FROM cf_projects WHERE user_id  =  ? AND id  =  ?", p.TxUserID, p.TxMaps.Int64["project_id"]).Int64()
		if err != nil {
			return p.ErrInfo(err)
		}
		if author == 0 {
			return p.ErrInfo("!funder || !author")
		}
	}

	forSign := fmt.Sprintf("%s,%s,%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["project_id"], p.TxMap["lang_id"], p.TxMap["comment"])
	CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false)
	if err != nil {
		return p.ErrInfo(err)
	}
	if !CheckSignResult {
		return p.ErrInfo("incorrect sign")
	}

	err = p.limitRequest(consts.LIMIT_CF_COMMENTS, "cf_comments", consts.LIMIT_CF_COMMENTS_PERIOD)
	if err != nil {
		return p.ErrInfo(err)
	}
	return nil
}
예제 #27
0
func (p *Parser) AdminVariablesFront() error {

	var Variables map[string]interface{}
	err := json.Unmarshal(p.TxMap["variables"], &Variables)
	if err != nil {
		return p.ErrInfo(err)
	}

	var VARIABLES_COUNT int
	if p.BlockData != nil && p.BlockData.BlockId < 29047 {
		VARIABLES_COUNT = 71
	} else {
		VARIABLES_COUNT = 72
	}
	err = p.generalCheckAdmin()
	if err != nil {
		return p.ErrInfo(err)
	}

	if len(Variables) != VARIABLES_COUNT {
		return p.ErrInfo(fmt.Sprintf("incorrect variables count (%d != %d)", len(Variables), VARIABLES_COUNT))
	}

	i := 0
	for name, value := range Variables {
		errorText := "incorrect variable %s"
		// проверим допустимые значения в value. Хотя админу и можно доверять, но лучше перестраховаться.
		switch name {
		case "alert_error_time", "error_time", "promised_amount_points", "promised_amount_votes_0", "promised_amount_votes_1", "promised_amount_votes_period", "holidays_max", "limit_abuses", "limit_abuses_period", "limit_promised_amount", "limit_promised_amount_period", "limit_cash_requests_out", "limit_cash_requests_out_period", "limit_change_geolocation", "limit_change_geolocation_period", "limit_holidays", "limit_holidays_period", "limit_message_to_admin", "limit_message_to_admin_period", "limit_mining", "limit_mining_period", "limit_node_key", "limit_node_key_period", "limit_primary_key", "limit_primary_key_period", "limit_votes_miners", "limit_votes_miners_period", "limit_votes_complex", "limit_votes_complex_period", "limit_commission", "limit_commission_period", "limit_new_miner", "limit_new_miner_period", "limit_new_user", "limit_new_user_period", "max_block_size", "max_block_user_transactions", "max_day_votes", "max_tx_count", "max_tx_size", "max_user_transactions", "miners_keepers", "miner_points", "miner_votes_0", "miner_votes_1", "miner_votes_attempt", "miner_votes_period", "mining_votes_0", "mining_votes_1", "mining_votes_period", "min_miners_keepers", "node_voting", "node_voting_period", "rollback_blocks_1", "rollback_blocks_2", "limit_change_host", "limit_change_host_period", "min_miners_of_voting", "min_hold_time_promise_amount", "min_promised_amount", "points_update_time", "reduction_period", "new_pct_period", "new_max_promised_amount", "new_max_other_currencies", "cash_request_time", "limit_for_repaid_fix", "limit_for_repaid_fix_period", "miner_newbie_time":
			if !utils.CheckInputData(value, "bigint") {
				return p.ErrInfo(fmt.Errorf(errorText, name))
			}
			i++
		case "points_factor":
			if !utils.CheckInputData(value, "float") {
				return p.ErrInfo(fmt.Errorf(errorText, name))
			}
			i++
		case "system_commission":
			if !utils.CheckInputData(value, "system_commission") {
				return p.ErrInfo(fmt.Errorf(errorText, name))
			}
			i++
		case "sleep":
			if !utils.CheckInputData(value, "sleep_var") {
				return p.ErrInfo(fmt.Errorf(errorText, name))
			}
			i++
		case "default":
			return p.ErrInfo(fmt.Errorf(errorText, name))
		}
	}

	if i != VARIABLES_COUNT {
		return p.ErrInfo(fmt.Sprintf("incorrect variables count (%d != %d)", i, VARIABLES_COUNT))
	}

	forSign := fmt.Sprintf("%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["variables"])
	CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false)
	if err != nil {
		return p.ErrInfo(err)
	}
	if !CheckSignResult {
		return p.ErrInfo("incorrect sign")
	}
	return nil
}
예제 #28
0
func (p *Parser) ChangeArbitratorConditionsFront() error {

	err := p.generalCheck()
	if err != nil {
		return p.ErrInfo(err)
	}

	if len(p.TxMap["conditions"]) > 3000 {
		return fmt.Errorf("incorrect conditions")
	}

	// может прийти [0]
	if p.TxMaps.String["conditions"] != "[0]" {

		var conditions map[string][5]string
		err = json.Unmarshal(p.TxMap["conditions"], &conditions)
		if err != nil {
			return p.ErrInfo(err)
		}
		if len(conditions) == 0 {
			return fmt.Errorf("len(conditions) == 0")
		}

		var currencyArray []string
		var minusCf int64
		for currencyId, data := range conditions {
			if !utils.CheckInputData(currencyId, "bigint") {
				return fmt.Errorf("incorrect currencyId")
			}
			if len(data) != 5 {
				return fmt.Errorf("incorrect data")
			}
			minAmount := utils.StrToFloat64(data[0])
			maxAmount := utils.StrToFloat64(data[1])
			minCommission := utils.StrToFloat64(data[2])
			maxCommission := utils.StrToFloat64(data[3])
			commissionPct := utils.StrToFloat64(data[4])

			if !utils.CheckInputData(data[0], "amount") || minAmount < 0.01 {
				return fmt.Errorf("incorrect minAmount")
			}
			if !utils.CheckInputData(data[1], "amount") {
				return fmt.Errorf("incorrect maxAmount")
			}
			if !utils.CheckInputData(data[2], "amount") || minCommission < 0.01 {
				return fmt.Errorf("incorrect minCommission")
			}
			if !utils.CheckInputData(data[3], "amount") {
				return fmt.Errorf("incorrect maxCommission")
			}
			if !utils.CheckInputData(data[4], "pct") || commissionPct > 10 || commissionPct < 0.01 {
				return fmt.Errorf("incorrect commissionPct")
			}
			if maxCommission > 0 && minCommission > maxCommission {
				return fmt.Errorf("minCommission > maxCommission")
			}
			if maxAmount > 0 && minAmount > maxAmount {
				return fmt.Errorf("minAmount > maxAmount")
			}
			// проверим, существует ли такая валюта в таблице DC-валют
			if ok, err := p.CheckCurrency(utils.StrToInt64(currencyId)); !ok {
				// если нет, то это может быть $currency_id 1000, которая определяет комиссию для всх CF-валют
				if currencyId != "1000" {
					return p.ErrInfo(err)
				}
			}
			if currencyId != "1000" {
				currencyArray = append(currencyArray, currencyId)
			} else {
				minusCf = 1
			}
		}
		count, err := p.Single("SELECT count(id) FROM currency WHERE id IN (" + strings.Join(currencyArray, ",") + ")").Int64()
		if err != nil {
			return p.ErrInfo(err)
		}
		if count != int64(len(conditions))-minusCf {
			return p.ErrInfo("count != int64(len(conditions)) - minusCf")
		}
	}

	if !utils.CheckInputData(p.TxMaps.String["url"], "arbitrator_url") && p.TxMaps.String["url"] != "0" {
		return fmt.Errorf("incorrect url")
	}

	forSign := fmt.Sprintf("%s,%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["conditions"], p.TxMap["url"])
	CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false)
	if err != nil {
		return p.ErrInfo(err)
	}
	if !CheckSignResult {
		return p.ErrInfo("incorrect sign")
	}

	err = p.limitRequest(consts.LIMIT_CHANGE_ARBITRATOR_CONDITIONS, "change_arbitrator_conditions", consts.LIMIT_CHANGE_ARBITRATOR_CONDITIONS_PERIOD)
	if err != nil {
		return p.ErrInfo(err)
	}
	return nil
}
예제 #29
0
파일: send_dc.go 프로젝트: dzyk/dcoin-go
func (p *Parser) SendDcFront() error {

	err := p.generalCheck()
	if err != nil {
		return p.ErrInfo(err)
	}

	verifyData := map[string]string{"from_user_id": "bigint", "to_user_id": "bigint", "currency_id": "bigint", "amount": "amount", "commission": "amount", "comment": "comment"}
	err = p.CheckInputData(verifyData)
	if err != nil {
		return p.ErrInfo(err)
	}

	if p.TxMaps.Float64["amount"] < 0.01 { // 0.01 - минимальная сумма
		return p.ErrInfo("amount")
	}

	// проверим, существует ли такая валюта в таблиуе DC-валют
	checkCurrency, err := p.CheckCurrency(p.TxMaps.Int64["currency_id"])
	if !checkCurrency {
		// если нет, то проверяем список CF-валют
		checkCurrency, err := p.CheckCurrencyCF(p.TxMaps.Int64["currency_id"])
		if err != nil {
			return p.ErrInfo(err)
		}
		if !checkCurrency {
			return p.ErrInfo("currency_id")
		}
	}

	nodeCommission, err := p.getMyNodeCommission(p.TxMaps.Int64["currency_id"], p.TxUserID, p.TxMaps.Float64["amount"])
	if err != nil {
		return p.ErrInfo(err)
	}

	// проверим, удовлетворяет ли нас комиссия, которую предлагает юзер
	if p.TxMaps.Float64["commission"] < nodeCommission {
		return p.ErrInfo(fmt.Sprintf("commission %v<%v", p.TxMaps.Float64["commission"], nodeCommission))
	}

	if p.BlockData != nil && p.BlockData.BlockId <= consts.ARBITRATION_BLOCK_START {
		for i := 0; i < 5; i++ {
			p.TxMaps.Float64["arbitrator"+utils.IntToStr(i)+"_commission"] = 0 // для check_sender_money
		}
		forSign := fmt.Sprintf("%s,%s,%s,%s,%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["to_user_id"], p.TxMap["amount"], p.TxMap["commission"], utils.BinToHex(p.TxMap["comment"]), p.TxMap["currency_id"])
		CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false)
		if err != nil {
			return p.ErrInfo(err)
		}
		if !CheckSignResult {
			return p.ErrInfo("incorrect sign")
		}
	} else {
		dupArray := make(map[int64]int64)
		for i := 0; i < 5; i++ {
			arbitrator__commission := "arbitrator" + utils.IntToStr(i) + "_commission"
			arbitrator_ := "arbitrator" + utils.IntToStr(i)
			if !utils.CheckInputData(p.TxMap[arbitrator__commission], "amount") {
				return p.ErrInfo("arbitrator_commission")
			}
			if !utils.CheckInputData(p.TxMap[arbitrator_], "bigint") {
				return p.ErrInfo("arbitrator")
			}
			// если указал ID арбитра, то должна быть комиссия для него
			if p.TxMaps.Int64[arbitrator_] > 0 && p.TxMaps.Float64[arbitrator__commission] < 0.01 {
				return p.ErrInfo("arbitrator_commission")
			}

			// на всяк случай не даем арбитрам возможность быть арбитрами самим себе
			if p.TxMaps.Int64[arbitrator_] == p.TxUserID {
				return p.ErrInfo("arbitrator = user_id")
			}

			if p.TxMaps.Int64[arbitrator_] > 0 {
				dupArray[utils.BytesToInt64(p.TxMap[arbitrator_])]++
				if dupArray[utils.BytesToInt64(p.TxMap[arbitrator_])] > 1 {
					return p.ErrInfo("doubles")
				}
			}
			if p.TxMaps.Int64[arbitrator_] > 0 {

				arbitrator := p.TxMap[arbitrator_]
				// проверим, является ли арбитром указанный user_id
				arbitratorConditionsJson, err := p.Single("SELECT conditions FROM arbitrator_conditions WHERE user_id  =  ?", utils.BytesToInt64(arbitrator)).Bytes()
				if err != nil {
					return p.ErrInfo(err)
				}
				arbitratorConditionsMap := make(map[string][5]string)
				err = json.Unmarshal(arbitratorConditionsJson, &arbitratorConditionsMap)
				// арбитр к этому моменту мог передумать и убрать свои условия, уйдя из арбитров для новых сделок поставив [0] что вызовет тут ошибку
				if err != nil {
					log.Debug("arbitratorConditionsJson", arbitratorConditionsJson)
					return p.ErrInfo(err)
				}
				// проверим, работает ли выбранный арбитр с валютой данной сделки
				var checkCurrency int64
				if p.TxMaps.Int64["currency_id"] > 1000 {
					checkCurrency = 1000
				} else {
					checkCurrency = p.TxMaps.Int64["currency_id"]
				}
				if len(arbitratorConditionsMap[utils.Int64ToStr(checkCurrency)]) == 0 {
					return p.ErrInfo("len(arbitratorConditionsMap[checkCurrency]) == 0")
				}
				// указан ли этот арбитр в списке доверенных у продавца
				sellerArbitrator, err := p.Single("SELECT user_id FROM arbitration_trust_list WHERE user_id  =  ? AND arbitrator_user_id  =  ?", p.TxMaps.Int64["to_user_id"], utils.BytesToInt64(arbitrator)).Int64()
				if err != nil {
					return p.ErrInfo(err)
				}
				if sellerArbitrator == 0 {
					return p.ErrInfo("sellerArbitrator == 0")
				}
				// указан ли этот арбитр в списке доверенных у покупателя
				buyerArbitrator, err := p.Single("SELECT user_id FROM arbitration_trust_list WHERE user_id  =  ? AND arbitrator_user_id  =  ?", p.TxMaps.Int64["from_user_id"], utils.BytesToInt64(arbitrator)).Int64()
				if err != nil {
					return p.ErrInfo(err)
				}
				if buyerArbitrator == 0 {
					return p.ErrInfo("buyerArbitrator == 0")
				}
				// согласен ли продавец на манибек
				arbitrationDaysRefund, err := p.Single("SELECT arbitration_days_refund FROM users WHERE user_id  =  ?", p.TxMaps.Int64["to_user_id"]).Int64()
				if err != nil {
					return p.ErrInfo(err)
				}
				if arbitrationDaysRefund == 0 {
					return p.ErrInfo("buyerArbitrator == 0")
				}
				// готов ли арбитр рассматривать такую сумму сделки
				currencyIdStr := utils.Int64ToStr(p.TxMaps.Int64["currency_id"])
				if p.TxMaps.Float64["amount"] < utils.StrToFloat64(arbitratorConditionsMap[currencyIdStr][0]) ||
					(p.TxMaps.Float64["amount"] > utils.StrToFloat64(arbitratorConditionsMap[currencyIdStr][1]) && utils.StrToFloat64(arbitratorConditionsMap[currencyIdStr][1]) > 0) {
					return p.ErrInfo("amount")
				}
				// мин. комиссия, на которую согласен арбитр
				minArbitratorCommission := utils.StrToFloat64(arbitratorConditionsMap[currencyIdStr][4]) / 100 * p.TxMaps.Float64["amount"]
				if minArbitratorCommission > utils.StrToFloat64(arbitratorConditionsMap[currencyIdStr][3]) && utils.StrToFloat64(arbitratorConditionsMap[currencyIdStr][3]) > 0 {
					minArbitratorCommission = utils.StrToFloat64(arbitratorConditionsMap[currencyIdStr][3])
				}
				if minArbitratorCommission < utils.StrToFloat64(arbitratorConditionsMap[currencyIdStr][2]) {
					minArbitratorCommission = utils.StrToFloat64(arbitratorConditionsMap[currencyIdStr][2])
				}
				if utils.BytesToFloat64(p.TxMap[arbitrator__commission]) < minArbitratorCommission {
					return p.ErrInfo(" < minArbitratorCommission")
				}
			}
		}

		forSign := fmt.Sprintf("%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["to_user_id"], p.TxMap["amount"], p.TxMap["commission"], p.TxMap["arbitrator0"], p.TxMap["arbitrator1"], p.TxMap["arbitrator2"], p.TxMap["arbitrator3"], p.TxMap["arbitrator4"], p.TxMap["arbitrator0_commission"], p.TxMap["arbitrator1_commission"], p.TxMap["arbitrator2_commission"], p.TxMap["arbitrator3_commission"], p.TxMap["arbitrator4_commission"], utils.BinToHex(p.TxMap["comment"]), p.TxMap["currency_id"])
		CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false)
		if err != nil {
			return p.ErrInfo(err)
		}
		if !CheckSignResult {
			return p.ErrInfo("incorrect sign")
		}
	}

	/*
			wallets_buffer сделан не для защиты от двойной траты, а для того, чтобы нода, которая генерит блок не записала
			двойное списание в свой блок, который будет отправлен другим нодам и будет ими отвергнут.
		   Для тр-ий типа new_forex_order используется простой запрет на запись в блок тр-ии new_forex_order+new_forex_order или
		   new_forex_order+send_dc и пр.
		   защита от двойного списания на основе даннных из блока, полученного из сети заключается в постепенной обработке
		   тр-ий путем проверки front_ и занесения данных в БД (ParseDataFull).
	*/
	amountAndCommission, err := p.checkSenderMoney(p.TxMaps.Int64["currency_id"], p.TxMaps.Int64["from_user_id"], p.TxMaps.Float64["amount"], p.TxMaps.Float64["commission"], p.TxMaps.Float64["arbitrator0_commission"], p.TxMaps.Float64["arbitrator1_commission"], p.TxMaps.Float64["arbitrator2_commission"], p.TxMaps.Float64["arbitrator3_commission"], p.TxMaps.Float64["arbitrator4_commission"])
	if err != nil {
		return p.ErrInfo(err)
	}

	// существует ли юзер-получатель
	err = p.CheckUser(p.TxMaps.Int64["to_user_id"])
	if err != nil {
		return p.ErrInfo(err)
	}

	err = p.checkSpamMoney(p.TxMaps.Int64["currency_id"], p.TxMaps.Float64["amount"])
	if err != nil {
		return p.ErrInfo(err)
	}

	// вычитаем из wallets_buffer
	// amount_and_commission взято из check_sender_money()
	err = p.updateWalletsBuffer(amountAndCommission, p.TxMaps.Int64["currency_id"])
	if err != nil {
		return p.ErrInfo(err)
	}

	return nil
}
예제 #30
0
func (p *Parser) ChangeCommissionFront() error {

	err := p.generalCheck()
	if err != nil {
		return p.ErrInfo(err)
	}

	// является ли данный юзер майнером
	err = p.checkMiner(p.TxUserID)
	if err != nil {
		return p.ErrInfo(err)
	}

	if len(p.TxMap["commission"]) > 3000 {
		return p.ErrInfo("len commission")
	}
	commissionMap := make(map[string][3]float64)
	err = json.Unmarshal(p.TxMaps.Bytes["commission"], &commissionMap)
	if err != nil {
		return p.ErrInfo(err)
	}
	var currencyArray []int64
	minusCf := 0
	for currencyId_, data := range commissionMap {

		currencyId := utils.StrToInt64(currencyId_)
		if len(data) != 3 {
			return p.ErrInfo("len(data) !=3")
		}
		if !utils.CheckInputData(currencyId, "int") {
			return p.ErrInfo("currencyId")
		}
		// % от 0 до 10
		if !utils.CheckInputData(utils.Float64ToStrPct(data[0]), "currency_commission") || data[0] > 10 {
			return p.ErrInfo("pct")
		}
		// минимальная комиссия от 0. При 0% будет = 0
		if !utils.CheckInputData(utils.Float64ToStrPct(data[1]), "currency_commission") {
			return p.ErrInfo("currency_min_commission")
		}
		// макс. комиссия. 0 - значит, считается по %
		if !utils.CheckInputData(utils.Float64ToStrPct(data[2]), "currency_commission") {
			return p.ErrInfo("currency_max_commission")
		}
		if data[1] > data[2] && data[2] > 0 {
			return p.ErrInfo("currency_max_commission")
		}
		// проверим, существует ли такая валюта в таблице DC-валют
		if ok, err := p.CheckCurrency(currencyId); !ok {
			// если нет, то это может быть $currency_id 1000, которая определяет комиссию для всх CF-валют
			if currencyId != 1000 {
				return p.ErrInfo(err)
			}
		}
		if currencyId != 1000 {
			currencyArray = append(currencyArray, currencyId)
		} else {
			minusCf = 1
		}
	}

	count, err := p.Single("SELECT count(id) FROM currency WHERE id IN (" + strings.Join(utils.SliceInt64ToString(currencyArray), ",") + ")").Int()
	if err != nil {
		return p.ErrInfo(err)
	}
	if count != len(commissionMap)-minusCf {
		return p.ErrInfo("count != len(commissionMap) - minusCf")
	}

	forSign := fmt.Sprintf("%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["commission"])
	CheckSignResult, err := utils.CheckSign(p.PublicKeys, forSign, p.TxMap["sign"], false)
	if err != nil || !CheckSignResult {
		return p.ErrInfo("incorrect sign")
	}

	err = p.limitRequest(p.Variables.Int64["limit_commission"], "commission", p.Variables.Int64["limit_commission_period"])
	if err != nil {
		return p.ErrInfo(err)
	}

	return nil
}