Exemple #1
0
    def bet_in(self, dic):
        change_type_41 = '41'  # 即时开中奖
        change_type_42 = '42'  # 即时开投注
        id = dic.get("game_instance_id", "")  # 项目id
        user_id = dic.get("user_id", "")  # 用户id
        user_channel_id = dic.get("user_channel_id", "")  # 用户下注渠道id
        conin_id = dic.get("coin_id", "")  # 投入币种id
        bet_amount = dic.get("bet_amount", "")  # 投注数量
        bet_start = dic.get("bet_start", 0)
        bet_end = dic.get("bet_end", 0)
        faker = True
        # merge_id = dic.get("merge_id", -1)  # 合并投注id
        # transaction_password = dic.get("transaction_password", "")  # 交易密码
        with MysqlTools().session_scope() as session:
            # 查询项目
            model = session.query(InstantGameInstanceModel).filter(
                InstantGameInstanceModel._id == id).first()
            template = session.query(InstantGameTemplateModel). \
                order_by(InstantGameTemplateModel._id.desc()).first()
            if model is None:
                return self.return_error(60001)
            if model.status == 1:
                return self.return_error(60002)
            if model.status == 2:
                return self.return_error(60003)
            if model.status == 0:
                can_bet = model.need - model.bet_number
                if can_bet <= 0:
                    return self.return_error(60002)
                if int(bet_amount) > can_bet:
                    return self.return_error(60004)

            if model.support_token >= 0 and int(
                    conin_id) != model.support_token and int(conin_id) != int(
                        _COIN_ID_EXP):
                return self.return_error(60008)

            if int(bet_amount) > model.need * (model.max_bet_ratio / 100):
                return self.return_error(40025)

            # 查询币价 币种实际需要金额
            exchange_rate = get_exchange_rate(int(conin_id))

            # (投注数量 * 投注单位) / 投注币种兑换usdt比例
            bet_money = (int(bet_amount) *
                         model.bet_unit) / exchange_rate['price']

            # 体验金相关逻辑
            if int(conin_id) == int(_COIN_ID_EXP):
                # 检查本次投注体验金使用数量 (允许范围: 1~10)
                if int(bet_amount) < 1 or int(bet_amount) > 10:
                    self.return_error(60015)
                # 体验金使用额度
                exp = int(model.experience / 100 * model.need)
                # 检查项目体验金占比剩余额度以及个人当天最大体验金使用额度(每天最多用10个)
                limit = self.check_instance_exp_limit(session, user_id,
                                                      model.game_serial)
                # instance_limit = limit['instance_limit']
                user_limit = limit['user_limit']
                total_pay_number = limit['total_pay_number']
                if user_limit > 10 - int(bet_amount):
                    self.return_error(60017)
                # if instance_limit >= exp:
                #     self.return_error(60016)
                if total_pay_number >= int(
                        model.need) * model.reward_quantity * (
                            (100 + template.exceeded_ratio) / 100):
                    model.full_load_time = datetime.datetime.utcnow()
                    faker = False
            else:
                limit = self.check_instance_exp_limit(session, user_id,
                                                      model.game_serial)
                total_pay_number = limit['total_pay_number']
                raise_logger("总下注金额" + "USDT:" + str(total_pay_number),
                             "game_publish_lottery", "info")
                if total_pay_number >= int(
                        model.need) * model.reward_quantity * (
                            (100 + template.exceeded_ratio) / 100):
                    model.full_load_time = datetime.datetime.utcnow()
                    faker = False

            # 查询用户资产
            account_service = AccountService()
            user_info = account_service.get_inner_user_account_by_token(
                session, user_id, conin_id)
            if isinstance(user_info, int):
                if user_info == 20001:
                    return self.return_error(20001)

            balance = get_decimal(user_info.get("balance"),
                                  digits=8,
                                  decimal_type="down")

            # 账户余额 < 需要下注金额
            if balance < bet_money:
                return self.return_error(60005)

            # 获取下注编号
            numbers = []
            user_lottery_num_list = []
            i = int(bet_amount)
            # start_num = random.randint(1, model.need 0- int(bet_amount))
            bet_start = int(bet_start)
            bet_end = int(bet_end)
            user_lottery_num_list.append(bet_start)
            user_lottery_num_list.append(bet_end)
            while i > 0:
                numbers.append(bet_start)
                bet_start += 1
                i -= 1
            if isinstance(numbers, list):
                nick_name = account_service.get_inner_user_account_info(
                    session, user_id).get("nick_name")
                # 添加参与记录
                participate_in_model = ParticipateInModel(
                    game_instance_id=0,
                    template_id=model.template_id,
                    game_serial=model.game_serial,
                    game_title=model.game_title,
                    release_type=model.release_type,
                    bet_token=model.bet_token,
                    bet_unit=model.bet_unit,
                    user_id=user_id,
                    nick_name=nick_name,
                    channel=user_channel_id,
                    bet_number=int(bet_amount),
                    pay_token=int(conin_id),
                    pay_number=get_decimal(bet_money,
                                           digits=8,
                                           decimal_type="down"),
                    award_numbers=json.dumps(numbers),
                    user_type=0,
                    merge_id=-1)
                session.add(participate_in_model)
                session.flush()
                # raise_logger("add participate_in_model", "game_bet_in", "info")
                # 提交扣款申请
                result = account_service.do_bet(
                    session, user_id, conin_id,
                    get_decimal(bet_money, digits=8, decimal_type="down"),
                    str(participate_in_model._id), int(bet_amount),
                    model.game_serial, user_channel_id, change_type_42)
                # raise_logger("do_bet success", "game_bet_in", "info")
                if isinstance(result, int):
                    if result == 0:
                        instant_game_service = InstantGameModelService()
                        # print('user_lottery_num_list-=-=', user_lottery_num_list)
                        # print('model.need-=-=', model.need)
                        # print('faker-=-=', faker)
                        lottery_result = WalletEosService().\
                            lottery_instant_adduce(get_timestamp(), user_lottery_num_list, model.need, faker)
                        # print('lottery_result-=-=', lottery_result)
                        if not any(lottery_result):
                            raise_logger("lottery_result empty", "game_bet_in",
                                         "info")
                            session.rollback()
                            return self.return_error(40026)
                        # 开奖
                        hash_numbers = lottery_result['block_hash']
                        raise_logger(
                            "项目:" + str(id) + "   中奖区块号:" + str(hash_numbers),
                            "game_publish_lottery", "info")
                        if hash_numbers == "":
                            raise_logger("开奖异常:80001", "game_publish_lottery",
                                         "info")
                            return False
                        # prize_number = int(hash_numbers, 16) % model.need + 1
                        prize_number = lottery_result['lottery_num']
                        raise_logger(
                            "项目:" + str(id) + "    中奖号码:" + str(prize_number),
                            "game_publish_lottery", "info")
                        participate_in_model.win_number = prize_number
                        participate_in_model.block_no = lottery_result[
                            'block_num']
                        participate_in_model.bet_hash = hash_numbers
                        participate_in_model.received_time = lottery_result[
                            'timestamp']
                        # 中奖
                        is_win = False
                        if prize_number in numbers:
                            is_win = True
                            participate_in_model.result = 1
                            model.lottery_time = datetime.datetime.utcnow()
                            instant_game_service.automatic_release(
                                session, model.template_id)
                            do_win = account_service.do_win(
                                session, user_id, model.reward_token,
                                model.reward_quantity,
                                str(participate_in_model._id), int(bet_amount),
                                model.game_serial, change_type_41)
                            if isinstance(do_win, int) is False:
                                raise_logger("分钱失败" + "user:"******"game_publish_lottery", "info")
                                session.rollback()
                                return False
                            if do_win != 0:
                                raise_logger("分钱失败" + "user:"******"game_publish_lottery", "info")
                                session.rollback()
                                return False

                        session.commit()

                        return {
                            'is_win': is_win,
                            'prize_number': prize_number,
                            'part_in_id': participate_in_model._id
                        }
                    else:
                        session.rollback()
                        return self.return_error(60009)
                else:
                    session.rollback()
                    return self.return_error(60010)
            else:
                session.rollback()
                return self.return_error(60007)
    def get_node_url(coin_id, mold="server", node_env=None, pattern=None):
        filters = {}
        if not node_env:
            node_env = get_env()
        filters["coin_id"] = coin_id
        filters["node_env"] = node_env
        if mold == "server":
            filters["server_status"] = _ONE_S
        else:
            filters["script_status"] = _ONE_S
        conn = None
        with MysqlTools().session_scope() as session:
            node = session.query(TokenNodeConfModel).filter_by(
                **filters).first()
            if node:
                url, port = node.node_url, node.node_port
                if coin_id == _ZERO_S:
                    conn, err = TokenNodeConfModel.check_btc(url, port)
                elif coin_id == _SIXTY_S:
                    conn, err = TokenNodeConfModel.check_eth(url, port)
                elif coin_id == _COIN_ID_EOS:
                    conn, err = TokenNodeConfModel.check_eos(
                        url, port, node.api_key, pattern)

                if conn:
                    if node.mark != "":
                        node.mark = ""
                        session.commit()
                    return conn
                else:
                    if mold == "server":
                        node.server_status = _ZERO_S
                    else:
                        node.script_status = _ZERO_S
                    node.mark = err

            if mold == "server":
                del filters["server_status"]
            else:
                del filters["script_status"]
            node_list = session.query(TokenNodeConfModel).filter_by(
                **filters).all()
            if not node_list:
                raise Exception("db not have available node!")
            for next_node in node_list:
                url, port = next_node.node_url, next_node.node_port
                if coin_id == _ZERO_S:
                    conn, err = TokenNodeConfModel.check_btc(url, port)
                elif coin_id == _SIXTY_S:
                    conn, err = TokenNodeConfModel.check_eth(url, port)
                elif coin_id == _COIN_ID_EOS:
                    conn, err = TokenNodeConfModel.check_eos(
                        url, port, node.api_key)
                if conn:
                    if mold == "server":
                        next_node.server_status = _ONE_S
                    else:
                        next_node.script_status = _ONE_S
                    if next_node.mark != "":
                        next_node.mark = ""
                    break
                else:
                    next_node.mark = err
            session.commit()
            if conn:
                return conn
        raise Exception("db not have available node!")
Exemple #3
0
 def get_instant_part_in_list(self,
                              limit,
                              offset,
                              game_serial='',
                              bet_time_start='',
                              bet_time_end='',
                              result='',
                              user_name='',
                              start_id=None):
     offset = get_offset_by_page(offset, limit)
     result_dict = {
         'limit': limit,
         'offset': offset,
         'count': 0,
         'content': [],
         'total': 0
     }
     with MysqlTools().session_scope() as session:
         account_service = AccountService()
         q = session.query(ParticipateInModel)
         if user_name != '':
             q = q.filter(ParticipateInModel.nick_name == user_name)
         if game_serial != '':
             q = q.filter(ParticipateInModel.game_serial == game_serial)
         if bet_time_start != '':
             q = q.filter(ParticipateInModel.created_at >= bet_time_start)
         if bet_time_end != '':
             q = q.filter(ParticipateInModel.created_at <= bet_time_end)
         if result != '':
             q = q.filter(ParticipateInModel.result == result)
         game_instance_id = 0
         q = q.filter(
             ParticipateInModel.game_instance_id == game_instance_id)
         record_count = q.count()
         result_dict['total'] = record_count
         result_dict['count'] = get_page_by_offset(record_count, limit)
         if start_id is not None:
             start_id = str(start_id)
             q = q.filter(ParticipateInModel._id < start_id)
         q = q.order_by(ParticipateInModel.created_at.desc())
         participate_in_list = q.limit(limit).offset(offset).all()
         for participate in participate_in_list:
             # user_type 0:真实用户  1:机器人
             if participate.user_type == 0:
                 user_info = account_service.get_inner_user_account_info(
                     session, participate.user_id)
                 user_name = user_info['nick_name']
             else:
                 user_name = participate.nick_name
             is_win = False
             if participate.win_number in participate.award_numbers:
                 is_win = True
             result_dict['content'].append({
                 "id":
                 participate._id,
                 "user":
                 user_name,
                 "bet_time":
                 str(participate.created_at),
                 "channel":
                 participate.channel,
                 "bet_token":
                 self.get_coin_name(participate.bet_token),
                 "bet_unit":
                 participate.bet_unit,
                 "bet_number":
                 decimal_to_str(participate.bet_number, 8),
                 "pay_token":
                 self.get_coin_name(participate.pay_token),
                 "pay_number":
                 decimal_to_str(participate.pay_number, 8),
                 'game_serial':
                 participate.game_serial,
                 "is_win":
                 is_win
             })
     return result_dict
Exemple #4
0
    def send_transaction(self, args):
        """
        "order_no", "parameter", "sign"
        :param args:
        :return:
        """
        order_no = args.get("order_no", "")
        parameter = args.get("parameter", "")
        sign = args.get("sign", "")
        check_flag = None
        coin_id = None
        symbol = None
        address = None
        calc = None
        if not order_no or not sign:
            self.return_error(20003)
        if isinstance(sign, dict):
            sign_tmp = sign
            for k, v in sign_tmp.items():
                if isinstance(v, bytes):
                    sign_tmp[k] = str(v, encoding="utf8")
            sign_log = json.dumps(sign_tmp)
        else:
            sign_log = str(sign)

        if isinstance(parameter, dict):
            coin_id = parameter.get("coin_id", "")
            address = parameter.get("address", "")
            symbol = parameter.get("symbol", "")
            calc = parameter.get("calc", "")
            if coin_id and address and symbol:
                check_flag = True
        if not check_flag:
            self.return_error(20003)

        # 判断币种类型合法性
        if coin_id not in self.symbol_to_model:
            self.return_error(90002)

        # 判断钱包类型合法性
        if symbol not in self.category:
            self.return_error(90004)

        # 获取对应model
        chain_model = self.symbol_to_model[coin_id][self.category[symbol]]

        # 查询结果,并记录流水
        with MysqlTools().session_scope() as session:
            record = session.query(RecordSignModel).filter(RecordSignModel.order_no == order_no).first()
            if record:
                self.return_error(10008)

            wallet = session.query(chain_model).filter(chain_model.sub_public_address == address).first()
            if not wallet:
                self.return_error(90003)

            public_key_aes = wallet.acct_public_key_aes
            private_key_aes = wallet.sub_private_key_aes

            salt = session.query(TokenSaltModel).filter(TokenSaltModel.public_key_aes == public_key_aes).first()
            if not salt:
                self.return_error(90005)
            key = salt.key_aes
            nonce = salt.nonce_aes

            record_sign = RecordSignModel(
                order_no=order_no,
                coin_id=coin_id,
                parameter=json.dumps(parameter),
                sign=sign_log
            )
            session.add(record_sign)
            session.commit()

        # 处理私钥
        sub_private_key = None
        if coin_id in [_ZERO_S, _SIXTY_S]:
            try:
                sub_private_key = super_deAES(private_key_aes, key, nonce)
            except Exception as e:
                self.return_error(90005, str(e))

        # 发送交易
        if coin_id == _ZERO_S:
            # btc交易
            tx_info, do_result = self.btc_send_tx(sign, sub_private_key, calc)
        elif coin_id == _SIXTY_S:
            # eth交易
            tx_info, do_result = self.eth_send_tx(sign, sub_private_key)
        elif coin_id == _COIN_ID_EOS:
            # eos交易
            tx_info, do_result = self.eos_send_tx(sign)
        else:
            tx_info = do_result = ""

        # 记录结果
        response = {
            "data": tx_info,
            "status": do_result
        }
        with MysqlTools().session_scope() as session:
            record_finally = session.query(RecordSignModel).filter(RecordSignModel.order_no == order_no).first()
            record_finally.response = json.dumps(response)
            record_finally.do_result = do_result
            session.commit()
        return response
Exemple #5
0
class TokenSyncBlockEosScript(object):
    ec = None
    sync_success = _ONE
    sync_fail = _ZERO
    eos_coin_id = _COIN_ID_EOS
    slog = Slog("token_sync_block_eos_script")
    mysql_tool = MysqlTools()
    wait_lottery_dict = {}

    def __init__(self):
        self.ec = TokenNodeConfModel.get_eos_node_script(script_unit=_ZERO_S)  # 获取eos connect连接
        # pass

    def get_local_block_num(self):
        """
        获取本地区块的高度
        :return:
        """
        with self.mysql_tool.session_scope() as session:
            f_filter = {
                "status": self.sync_success,
                "coin_id": self.eos_coin_id
            }
            local_block = session.query(SyncBlockModel).filter_by(**f_filter).first()
        if not local_block:
            raise Exception("Mysql database SyncBlockModel lacks configuration data")
        local_block_num = local_block.block_no

        return local_block_num

    def get_remote_block_num(self):
        """
        获取远端节点的最新区块高度
        :return:
        """
        remote_block = self.ec.http_get_latest_block()
        remote_block_num = remote_block.get("block_num", "")
        if not remote_block_num:
            raise Exception("Remote eos node has error")
        return remote_block_num

    def async_block_multi(self, begin=None, end=None, sync_block_num_list=None):
        block_data_dict = {}
        thread_list = []
        if not sync_block_num_list:
            for j in range(begin, end):
                t = threading.Thread(target=self._get_block_detail, args=(block_data_dict, j))
                t.setDaemon(True)
                thread_list.append(t)
            for t in thread_list:
                t.start()
            for t in thread_list:
                t.join()
        else:
            for j in sync_block_num_list:
                t = threading.Thread(target=self._get_block_detail, args=(block_data_dict, j))
                t.setDaemon(True)
                thread_list.append(t)
            for t in thread_list:
                t.start()
            for t in thread_list:
                t.join()

        return block_data_dict

    def _get_block_detail(self, block_data_dict, temp_remote_block_num):
        temp_insert_block_data = self.ec.http_get_block_detail(temp_remote_block_num)
        block_data_dict[str(temp_remote_block_num)] = temp_insert_block_data

    def sync_block(self, local_block_num, remote_block_num, interval=8):
        """
        同步区块,默认每8个块创建一个session scope,防止长连接
        同步到SyncEosModel
        同步到SyncBlockModel
        :param local_block_num: 本地block num
        :param remote_block_num: 远程block num
        :param interval: 创建MySQL链接的块数间隔
        :return:
        """
        for i in range(local_block_num + 1, remote_block_num, interval):
            temp_remote_block_num = i + interval
            if temp_remote_block_num > remote_block_num:
                temp_remote_block_num = remote_block_num
            sync_eos_model_list = []
            temp_last_sync_block_no = None
            temp_last_sync_block_hash = ""
            # 调用协程读取
            block_data_dict = self.async_block_multi(i, temp_remote_block_num)
            btime = time.time()
            block_data_dict_keys = []
            eos_model_dict = {}
            with self.mysql_tool.session_scope() as session_select:
                for block_no_item in range(i, temp_remote_block_num):
                    block_data_dict_keys.append(block_no_item)
                    temp_last_sync_block_no = block_no_item
                    temp_insert_block_data = block_data_dict.get(str(block_no_item), {})
                    if not temp_insert_block_data:
                        time_stamp_decimal = get_decimal(block_no_item, digits=3) * -1
                        temp_last_sync_block_hash = ""
                        eos_model = SyncEosModel(
                            block_num=int(block_no_item),
                            time_stamp_decimal=time_stamp_decimal,
                            status=self.sync_fail
                        )
                        sync_eos_model_list.append(eos_model)
                        eos_model_dict[str(block_no_item)] = eos_model
                    else:
                        time_stamp = temp_insert_block_data.get("timestamp", "")
                        if time_stamp:
                            time_stamp_decimal = get_decimal(str_to_timestamp(time_stamp), digits=3)
                            temp_last_sync_block_hash = temp_insert_block_data.get("id")
                            eos_model = SyncEosModel(
                                block_num=temp_insert_block_data.get("block_num"),
                                block_hash=temp_last_sync_block_hash,
                                time_stamp=time_stamp,
                                time_stamp_decimal=time_stamp_decimal,
                                previous=temp_insert_block_data.get("previous"),
                                status=self.sync_success
                            )
                            sync_eos_model_list.append(eos_model)
                            eos_model_dict[str(block_no_item)] = eos_model
                    self.slog.info("sync block_num:", temp_last_sync_block_no, "sync block_hash:", temp_last_sync_block_hash)
            if sync_eos_model_list:
                session_select.add_all(sync_eos_model_list)
                try:
                    session_select.query(SyncBlockModel).filter(SyncBlockModel.coin_id == self.eos_coin_id).update({
                        SyncBlockModel.block_no: temp_last_sync_block_no,
                        SyncBlockModel.block_hash: temp_last_sync_block_hash})
                    session_select.commit()
                except Exception as e:
                    self.slog.error(str(e))
                    print("insert error,about have duplicate data")
                    try:
                        sync_eos_model_list = []
                        with self.mysql_tool.session_scope() as session_select:
                            already_sync_eos_models = session_select.query(SyncEosModel).filter(SyncEosModel.block_num.in_(block_data_dict_keys)).all()
                            if already_sync_eos_models:
                                for already_sync_eos_model in already_sync_eos_models:
                                    already_sync_eos_block_num = already_sync_eos_model.block_num
                                    if already_sync_eos_block_num and already_sync_eos_block_num in block_data_dict_keys:
                                        block_data_dict_keys.remove(already_sync_eos_block_num)
                            for block_data_dict_key in block_data_dict_keys:
                                sync_eos_model_list.append(eos_model_dict[str(block_data_dict_key)])
                            session_select.add_all(sync_eos_model_list)

                            session_select.query(SyncBlockModel).filter(SyncBlockModel.coin_id == self.eos_coin_id).update({
                                SyncBlockModel.block_no: temp_last_sync_block_no,
                                SyncBlockModel.block_hash: temp_last_sync_block_hash})
                            session_select.commit()
                    except Exception as e:
                        self.slog.error(str(e))
                    print("insert time " + str(time.time() - btime))
        return True

    def process_game_list(self):
        f_filters = {
            "block_hash": "",
            "status": _ZERO
        }

        with self.mysql_tool.session_scope() as session:
            base_block_num_not_have_model_list = session.query(GameGetLotteryBlockInfoEosModel).filter(GameGetLotteryBlockInfoEosModel.base_block_num < _ZERO).all()
            if base_block_num_not_have_model_list:
                for base_block_num_not_have_model in base_block_num_not_have_model_list:
                    base_time_stamp = base_block_num_not_have_model.base_time_stamp
                    lottery_block_add = base_block_num_not_have_model.block_num
                    confirm_block_add = base_block_num_not_have_model.confirm_block_num
                    base_block = session.query(SyncEosModel).filter(SyncEosModel.time_stamp_decimal >= base_time_stamp).order_by(SyncEosModel.block_num.asc()).first()
                    if base_block and base_block.time_stamp_decimal - base_time_stamp <= _SIXTY:
                        base_block_num = base_block.block_num
                        base_block_num_not_have_model.base_block_num = base_block_num
                        base_block_num_not_have_model.block_num = base_block_num + lottery_block_add
                        base_block_num_not_have_model.confirm_block_num = base_block_num + lottery_block_add + confirm_block_add
                        session.commit()

            wait_lottery_model_list = session.query(GameGetLotteryBlockInfoEosModel).filter_by(**f_filters).filter(GameGetLotteryBlockInfoEosModel.base_block_num > _ZERO).all()
            if wait_lottery_model_list:
                wait_lottery_dict = {}
                wait_lottery_list = []
                for lottery_info_model in wait_lottery_model_list:
                    wait_lottery_dict[str(lottery_info_model.confirm_block_num)] = {
                        "game_instance_id": lottery_info_model.game_instance_id, "block_num": lottery_info_model.block_num}
                    wait_lottery_list.append(lottery_info_model.confirm_block_num)

                sync_eos_model_list = session.query(SyncEosModel).filter(
                    SyncEosModel.block_num.in_(wait_lottery_list), SyncEosModel.status == self.sync_success).all()

                if sync_eos_model_list:
                    for sync_eos_model in sync_eos_model_list:
                        confirm_block_num = sync_eos_model.block_num
                        game_instance_id = wait_lottery_dict[str(confirm_block_num)]["game_instance_id"]
                        block_no = wait_lottery_dict[str(confirm_block_num)]["block_num"]
                        lottery_eos_model = session.query(SyncEosModel).filter(SyncEosModel.block_num == block_no).first()
                        if lottery_eos_model:
                            block_hash = lottery_eos_model.block_hash
                            sync_eos = self.update_sync_eos(session, block_no, block_hash)
                            if sync_eos:
                                block_hash = sync_eos["block_hash"]
                                received_time = timestamp = sync_eos["time_stamp"]
                                TokenSyncBlockEosScript.lottery_callback(session, game_instance_id, block_no, block_hash, timestamp, received_time)
                                if str(confirm_block_num) in wait_lottery_dict:
                                    del wait_lottery_dict[str(confirm_block_num)]
                                session.commit()
                self.wait_lottery_dict = wait_lottery_dict
        return True

    def update_sync_eos(self, session, block_num, block_hash):
        """
        开奖时,如果再次查询节点上的该区块,如果hash有变化,说明回滚,取最新区块详情,修改该区块
        :param session:
        :param block_num:
        :param block_hash:
        :return:
        """
        block_detail = self.ec.http_get_block_detail(block_num)
        if block_detail:
            remote_block_hash = block_detail.get("id", "")
            time_stamp = block_detail.get("timestamp", "")
            if remote_block_hash:
                if remote_block_hash != block_hash:
                    sync_eos_model = session.query(SyncEosModel).filter(SyncEosModel.block_num == block_num).first()
                    if sync_eos_model:
                        time_stamp_decimal = get_decimal(str_to_timestamp(time_stamp), digits=3)
                        previous = block_detail.get("previous", "")
                        sync_eos_model.block_hash = remote_block_hash
                        sync_eos_model.time_stamp = time_stamp
                        sync_eos_model.time_stamp_decimal = time_stamp_decimal
                        sync_eos_model.previous = previous
                        sync_eos_model.status = self.sync_success
                        self.slog.info("lottery block_num:", block_num, "lottery block_hash:", remote_block_hash)

                return {
                    "block_hash": remote_block_hash,
                    "time_stamp": time_stamp,
                }
        return {}

    @staticmethod
    def lottery_callback(session, game_instance_id, block_no, block_hash, timestamp, received_time):
        """

        :param session:
        :param game_instance_id:
        :param block_no:
        :param block_hash:
        :param timestamp:
        :param received_time:
        :return:
        """
        process_res = WalletEosService.lottery_callback(game_instance_id, block_no, block_hash, timestamp, received_time)
        session.query(GameGetLotteryBlockInfoEosModel).filter(
            GameGetLotteryBlockInfoEosModel.game_instance_id == game_instance_id).update({
            GameGetLotteryBlockInfoEosModel.block_hash: block_hash,
            GameGetLotteryBlockInfoEosModel.time_stamp: timestamp,
            GameGetLotteryBlockInfoEosModel.status: process_res
        })
        return True

    def work(self):
        # 1.查询已经同步的区块高度
        local_block_num = self.get_local_block_num()
        # 2.查询当前节点的区块最新高度
        remote_block_num = self.get_remote_block_num()
        # local_block_num, remote_block_num = 37657192, 37657202
        # 3.遍历区块号,8个块创建一个session scope
        sync_res = self.sync_block(local_block_num, remote_block_num)
        return sync_res
Exemple #6
0
    def main_page(self):
        with MysqlTools().session_scope() as session:
            account_service = AccountService()
            banners = []
            announcements = []
            participates = []
            instance_info = {}
            merges = []
            banner_list = session.query(BannerManageModel). \
                filter(BannerManageModel.status == 1).all()
            if len(banner_list) > 0:
                for banner in banner_list:
                    banners.append({
                        'image': banner.image,
                        'site': banner.site
                    })
            announcement_list = session.query(AnnouncementManageModel). \
                filter(AnnouncementManageModel.status == 1).all()
            if len(announcement_list) > 0:
                for announcement in announcement_list:
                    announcements.append({
                        'title': announcement.title,
                        'site': announcement.site
                    })
            participate_list = session.query(ParticipateInModel). \
                order_by(ParticipateInModel.created_at.desc()).limit(5).offset(0).all()
            if len(participate_list) > 0:
                for participate in participate_list:
                    if participate.user_type == 0:
                        user_info = account_service.get_inner_user_account_info(
                            session, participate.user_id)
                        user_name = user_info['nick_name']
                    else:
                        user_name = participate.nick_name
                    participates.append({
                        "user":
                        user_name,
                        "bet_time":
                        str(participate.created_at),
                        "channel":
                        participate.channel,
                        "bet_token":
                        participate.bet_token,
                        "bet_number":
                        participate.bet_number,
                        "pay_token":
                        participate.pay_token,
                        "pay_number":
                        str(participate.pay_number)
                    })
            instance = session.query(GameDigitalInstanceModel). \
                order_by(GameDigitalInstanceModel.status.asc(),
                         GameDigitalInstanceModel.created_at.desc()).first()

            ins_instance = session.query(InstantGameInstanceModel). \
                order_by(InstantGameInstanceModel.status.asc(),
                         InstantGameInstanceModel.created_at.desc()).first()
            if ins_instance is None:
                ins_instance = {
                    'id': '',
                    'game_serial': '',
                    # 'game_title': instance.game_title,
                    # 'game_describe': instance.game_describe,
                    # 'status': instance.status,
                    'support_token': '',
                    'reward_token': '',
                    'reward_quantity': '',
                }
            else:
                ins_instance = {
                    'id': ins_instance._id,
                    'game_serial': ins_instance.game_serial,
                    'support_token': ins_instance.support_token,
                    'reward_token': ins_instance.reward_token,
                    'reward_quantity': ins_instance.reward_quantity,
                }
            winner = ''
            bet_serial = ''
            bet_number = 0
            merge_id = -1
            if instance is not None:
                merge_list = session.query(MergeParticipateInModel). \
                    filter(MergeParticipateInModel.game_instance_id == instance._id). \
                    order_by(MergeParticipateInModel.created_at.desc()).limit(3).offset(0).all()
                if len(merge_list) > 0:
                    merge_id = 1
                    for merge in merge_list:
                        initiate_user = account_service.get_inner_user_account_info(
                            session, merge.initiate_user_id)
                        merges.append({
                            'merge_id':
                            merge._id,
                            'name':
                            initiate_user['nick_name'],
                            'portrait':
                            initiate_user['profile_picture']
                        })
                if instance.status == 2:
                    winning_record = session.query(WinningRecordModel). \
                        filter(WinningRecordModel.game_instance_id == instance._id).first()
                    if winning_record is not None:
                        if winning_record.user_type == 0:
                            account_service = AccountService()
                            user_info = account_service.get_inner_user_account_info(
                                session, winning_record.user_id)
                            winner = user_info['nick_name']
                        elif winning_record.user_type == 1:
                            robot = session.query(RobotAccountModel).filter(
                                RobotAccountModel.user_id ==
                                winning_record.user_id).first()
                            winner = robot.nick_name
                        else:
                            winner = 'X@17Yau8'
                        bet_serial = winning_record.bet_serial
                        merge_id = winning_record.merge_id
                        bet_number = winning_record.bet_number
                # progress = 0
                progress = (instance.bet_number / instance.need) * 100
                if 0 < progress < 1:
                    progress = 1
                if progress > 1:
                    progress = int(progress)
                result = {
                    'banner_list': banners,
                    'announcement_list': announcements,
                    'ins_instance': ins_instance,
                    'instance': {
                        'id': instance._id,
                        'game_serial': instance.game_serial,
                        'game_title': instance.game_title,
                        'game_describe': instance.game_describe,
                        'progress': progress,
                        'remain': int(instance.need - instance.bet_number),
                        'status': instance.status,
                        'lottery_time': str(instance.lottery_time),
                        'winners': winner,
                        'bet_serial': bet_serial,
                        'bet_token': self.get_coin_name(instance.bet_token),
                        'bet_number': bet_number,
                        'reward_token':
                        self.get_coin_name(instance.reward_token),
                        'reward_quantity': instance.reward_quantity,
                        'merge_id': merge_id,
                        'merge_list': merges
                    },
                    'participate': participates
                }
            else:
                result = {
                    'banner_list': banners,
                    'announcement_list': announcements,
                    'instance': {},
                    'participate': participates
                }
        return result
Exemple #7
0
    def automatic_release_instance(self):
        # now = int(time.time())
        # time_struct = time.localtime(now)
        # str_time = time.strftime("%Y-%m-%d %H:%M:%S", time_struct)
        str_time = get_utc_now()

        with MysqlTools().session_scope() as session:
            template_result = session.query(GameDigitalTemplateModel). \
                filter(GameDigitalTemplateModel.template_status == 1,
                       GameDigitalTemplateModel.auto_release == 1).all()
            if len(template_result) > 0:
                for row in template_result:
                    btc_usdt_rate = get_exchange_rate(
                        row.reward_token)['price']
                    ceiling = row.need_ceiling
                    floor = row.need_floor
                    email_config = get_sms_email('common')
                    if email_config == {}:
                        self.return_error(35034)
                    send_email_config = get_sms_email("send_email_config")
                    subject = email_config['email_subject']
                    if btc_usdt_rate > ceiling or btc_usdt_rate < floor:
                        self.slog.info("instantiation fail. rate is ",
                                       str(btc_usdt_rate))
                        self.slog.info("game template id is ", str(row._id))
                        # 警告邮件
                        send_mail(
                            "game自动实例化失败, GAME模板id:" + str(row._id) +
                            ",奖励币种价格:" + str(btc_usdt_rate),
                            send_email_config['user'],
                            send_email_config['pwd'], email_config['email'],
                            subject, send_email_config['smtp_server'],
                            send_email_config['smtp_port'])
                    else:
                        template_id = row._id
                        instance_list = session.query(GameDigitalInstanceModel). \
                            filter(GameDigitalInstanceModel.status == 0,
                                   GameDigitalInstanceModel.template_id == template_id).all()
                        if len(instance_list) <= 0:
                            phase_prefix = row.phase_prefix
                            need = btc_usdt_rate * row.reward_quantity * (
                                (100 + row.exceeded_ratio) / 100)
                            game_serial = generate_phase(str(phase_prefix))
                            digital_instance_model = GameDigitalInstanceModel(
                                template_id=template_id,
                                game_serial=game_serial,
                                game_title=row.game_title,
                                bet_token=row.bet_token,
                                bet_unit=row.bet_unit,
                                support_token=row.support_token,
                                reward_token=row.reward_token,
                                reward_quantity=row.reward_quantity,
                                handling_fee=row.handling_fee,
                                game_describe=row.game_describe,
                                experience=row.experience,
                                merge_threshold=row.merge_threshold,
                                release_time=str_time,
                                need=int(need),
                                status=0,
                                release_type=1,
                                chain_status=0)
                            # if create_all_bet_number(game_serial, int(need)) != 2000:
                            #     self.slog.info("create all bet number fail")
                            if not GameNumberSetService().createNumbers(
                                {
                                    "game_serial": game_serial,
                                    "total": int(need)
                                }):
                                self.slog.info("create all bet number fail")
                                self.return_error(40015)
                            session.add(digital_instance_model)
                            session.flush()
                            try:
                                # 发布信息上链
                                if BlockChainInfoService(
                                ).insert_block_chain_info(
                                        '', str(digital_instance_model._id), 2,
                                    {
                                        "instance_id":
                                        digital_instance_model._id,
                                        "template_id":
                                        template_id,
                                        "game_serial":
                                        game_serial,
                                        "support_token":
                                        row.support_token,
                                        "bet_token":
                                        row.bet_token,
                                        "bet_unit":
                                        row.bet_unit,
                                        "reward_token":
                                        row.reward_token,
                                        "reward_quantity":
                                        row.reward_quantity,
                                        "handling_fee":
                                        str(row.handling_fee),
                                        "game_describe":
                                        row.game_describe,
                                        "release_time":
                                        str_time.strftime("%Y-%m-%d %H:%M:%S"),
                                        "status":
                                        0,
                                        "need":
                                        int(need),
                                        "release_type":
                                        0,
                                    }):
                                    digital_instance_model.chain_status = 1
                                    self.slog.info(
                                        "insert_block_chain_info success")
                                else:
                                    self.slog.info(
                                        "insert_block_chain_info fail")
                            except Exception as e:
                                self.slog.info("insert_block_chain_info fail")
                                self.slog.info(f"Exception: {e}")
                                # self.slog.info("automatic_release_instance fail")
                                # session.rollback()
                            session.commit()
                            # send_mail("game自动实例化成功, GAME模板id:" + str(template_id) + ",奖励币种价格:" + str(btc_usdt_rate),
                            #           send_email_config['user'], send_email_config['pwd'],
                            #           email_config['email'],
                            #           subject, send_email_config['smtp_server'], send_email_config['smtp_port'])
                            self.slog.info(
                                "automatic_release_instance success")
 def get_dice_award_rate(self, user_id):
     with MysqlTools().session_scope() as session:
         account_service = AccountService()
         award_rate_info = session.query(DiceParticipateInModel.user_dice,
                                         func.count(DiceParticipateInModel._id).label('total_award')). \
             filter(DiceParticipateInModel.dice_result == 0). \
             group_by(DiceParticipateInModel.user_dice).all()
         stone = 0
         scissors = 0
         cloth = 0
         # balance_btc = ''
         # balance_eth = ''
         # balance_usdt = ''
         # balance_eos = ''
         # balance_exp = ''
         # print(award_rate_info)
         account_balance = account_service.get_user_token_list(
             user_id, None, 1, 10)['content'][0]
         balance_btc = account_balance['BTC']
         balance_eth = account_balance['ETH']
         if account_balance.get('EOS', None) is not None:
             balance_eos = account_balance['EOS']
         else:
             balance_eos = 0
         balance_usdt = account_balance['USDT']
         balance_exp = account_balance['USDT_EXPERIENCE']
         if len(award_rate_info) > 0:
             award_total = 0
             for award_rate in award_rate_info:
                 award_total += award_rate[1]
                 if award_rate[0] == 0:
                     stone = award_rate[1]
                 elif award_rate[0] == 1:
                     scissors = award_rate[1]
                 elif award_rate[0] == 2:
                     cloth = award_rate[1]
             stone_rate = stone / award_total * 100
             scissors_rate = scissors / award_total * 100
             cloth_rate = cloth / award_total * 100
             result = {
                 'stone': decimal_to_str(stone_rate, 2),
                 'scissors': decimal_to_str(scissors_rate, 2),
                 'cloth': decimal_to_str(cloth_rate, 2),
                 'balance': {
                     'btc': decimal_to_str(balance_btc, 8),
                     'eth': decimal_to_str(balance_eth, 8),
                     'eos': decimal_to_str(balance_eos, 8),
                     'usdt': decimal_to_str(balance_usdt, 4),
                     'exp': decimal_to_str(balance_exp, 4)
                 }
             }
             # print(result)
             return result
         else:
             return {
                 'stone': '',
                 'scissors': '',
                 'cloth': '',
                 'balance': {
                     'btc': decimal_to_str(balance_btc, 8),
                     'eth': decimal_to_str(balance_eth, 8),
                     'eos': decimal_to_str(balance_eos, 8),
                     'usdt': decimal_to_str(balance_usdt, 4),
                     'exp': decimal_to_str(balance_exp, 4)
                 }
             }
    def dice_chip_in_fast(self, user_id, user_channel_id, coin_id, bet_amount,
                          user_dice):
        change_type_31 = '31'  # 扣款
        change_type_32 = '32'  # 返还
        change_type_33 = '33'  # 中奖
        with MysqlTools().session_scope() as session:
            # 查询用户资产
            account_service = AccountService()
            user_info = account_service.get_inner_user_account_by_token(
                session, user_id, coin_id)
            if isinstance(user_info, int):
                if user_info == 20001:
                    return self.return_error(20001)

            balance = get_decimal(user_info.get("balance"),
                                  digits=8,
                                  decimal_type="down")
            # 账户余额 < 需要下注金额
            bet_number = get_decimal(bet_amount, digits=4, decimal_type="down")
            if balance < bet_number:
                return self.return_error(60005)
            dice_serial = dice_generate_phase()
            # 获取最新eos区块,计算开奖区块高度
            dice_time = get_timestamp()
            ec = TokenNodeConfModel.get_eos_node_script(script_unit=_THREE_S)
            latest_eos_block_info = ec.http_get_latest_block()
            # print('latest_eos_block_info=-=-=', latest_eos_block_info)
            block_no = latest_eos_block_info['block_num']

            dice_part_in_model = DiceParticipateInModel(
                dice_serial=dice_serial,
                user_id=user_id,
                user_dice=user_dice,
                channel=user_channel_id,
                bet_number=bet_number,
                bet_token=coin_id,
                reward_token=coin_id,
                reward_quantity=bet_number,
                dice_timestamp=dice_time,
                block_no=block_no)
            session.add(dice_part_in_model)
            session.flush()
            # 提交扣款申请
            dice_part_id = dice_part_in_model._id
            result = account_service.do_bet(
                session, user_id, coin_id, bet_number,
                'dice_bet' + str(dice_part_in_model._id), 1, dice_serial,
                user_channel_id, change_type_31)
            if result != 0:
                session.rollback()
                raise_logger("do_bet result" + str(result), "game_bet_in",
                             "info")

            # -------------------------------- 开奖 -------------------------------- #
            block_timestamp = latest_eos_block_info['timestamp']
            block_hash = latest_eos_block_info['id']
            dice_result = -1
            banker_dice = int(block_hash, 16) % 3  # 0石头 1剪刀 2布
            user_dice = int(user_dice)
            if banker_dice == user_dice:
                dice_result = 1  # 0用户胜 1平局 2庄家胜 -1未知
            else:
                if banker_dice == 0 and user_dice == 1:
                    dice_result = 2
                elif banker_dice == 0 and user_dice == 2:
                    dice_result = 0
                elif banker_dice == 1 and user_dice == 0:
                    dice_result = 0
                elif banker_dice == 1 and user_dice == 2:
                    dice_result = 2
                elif banker_dice == 2 and user_dice == 0:
                    dice_result = 2
                elif banker_dice == 2 and user_dice == 1:
                    dice_result = 0
            dice_part_in_model.banker_dice = banker_dice
            dice_part_in_model.dice_result = dice_result
            dice_part_in_model.block_hash = block_hash
            dice_part_in_model.block_timestamp = block_timestamp
            # session.flush()
            change_type = change_type_32

            # ------------ 中奖控制 ------------ #
            winning_control = 0
            if dice_result in [0, 1]:
                win_dice_num = session.query(func.count(DiceParticipateInModel._id)). \
                    filter(DiceParticipateInModel.user_id == user_id,
                           DiceParticipateInModel.dice_result == 0,
                           func.date_format(DiceParticipateInModel.created_at, "%Y-%m-%d") ==
                           func.date_format(get_utc_now(), "%Y-%m-%d")).first()
                if win_dice_num[0] >= decimal.Decimal(500):
                    raise_logger(
                        "dice winning control userid = " + str(user_id),
                        "game_bet_in", "info")
                    dice_part_in_model.banker_dice = user_dice
                    dice_part_in_model.dice_result = 1
                    dice_result = 1
                    winning_control = 1
            # ------------ 中奖控制结束 ------------ #

            if dice_result in [0, 1]:
                reward_quantity = 0
                dice_config = session.query(DiceConfigModel). \
                    filter(DiceConfigModel.support_token_id == dice_part_in_model.bet_token).first()
                if dice_config is None:
                    return self.return_error(40022)
                if dice_result == 0:
                    change_type = change_type_33
                    # 用户获胜 中奖金额为投注金额+奖励金额(投注金额=奖励金额) 扣除手续费
                    reward_quantity = (dice_part_in_model.reward_quantity +
                                       dice_part_in_model.bet_number) * (
                                           100 -
                                           dice_config.handling_fee) / 100
                elif dice_result == 1:
                    change_type = change_type_32
                    # 平局 中奖金额为投注金额
                    reward_quantity = dice_part_in_model.bet_number
                result = account_service.do_win(
                    session, dice_part_in_model.user_id,
                    dice_part_in_model.reward_token, reward_quantity,
                    'dice_win' + str(dice_part_in_model._id),
                    dice_part_in_model.user_dice,
                    dice_part_in_model.dice_serial, change_type)
                if isinstance(result, int) is False:
                    raise_logger(
                        "dice分钱失败" + "user:"******"game_publish_lottery", "info")
                    session.rollback()
                    return False
                if result != 0:
                    raise_logger(
                        "dice分钱失败" + "user:"******"game_publish_lottery", "info")
                    session.rollback()
                    return False
            # -------------------------------- 开奖结束 -------------------------------- #

            session.commit()
            if winning_control == 1:
                return self.return_error(40023)
        return {
            'dice_result':
            dice_result,
            'banker_dice':
            banker_dice,
            'user_dice':
            user_dice,
            'dice_timestamp':
            timestamp_to_str(dice_time, format_style="%Y-%m-%d %H:%M:%S"),
            'dice_id':
            str(dice_part_id),
            'dice_serial':
            dice_serial,
            'reward_token':
            self.get_coin_name(coin_id),
            'reward_quantity':
            decimal_to_str(
                str((bet_number + bet_number) * decimal.Decimal(0.99)), 6)
        }
    def dice_chip_in(self, user_id, user_channel_id, coin_id, bet_amount,
                     user_dice):
        with MysqlTools().session_scope() as session:
            # 查询用户资产
            account_service = AccountService()
            user_info = account_service.get_inner_user_account_by_token(
                session, user_id, coin_id)
            if isinstance(user_info, int):
                if user_info == 20001:
                    return self.return_error(20001)

            balance = get_decimal(user_info.get("balance"),
                                  digits=8,
                                  decimal_type="down")
            # 账户余额 < 需要下注金额
            bet_number = get_decimal(bet_amount, digits=4, decimal_type="down")
            if balance < bet_number:
                return self.return_error(60005)
            dice_serial = dice_generate_phase()
            block_no = ''
            # 获取最新eos区块,计算开奖区块高度
            dice_time = get_timestamp()
            latest_eos_block_info = session.query(SyncEosModel). \
                order_by(SyncEosModel._id.desc()).first()
            latest_eos_block_no = latest_eos_block_info.block_num
            latest_eos_block_time = latest_eos_block_info.time_stamp_decimal
            block_delay = math.ceil(
                (dice_time - latest_eos_block_time) / decimal.Decimal(0.5))
            block_no = latest_eos_block_no + block_delay + 1
            # raise_logger("最新区块高度=" + str(latest_eos_block_no) + "时间:" + get_utc_now().strftime(
            #     "%Y-%m-%d %H:%M:%S.%f"), "game_bet_in", "info")
            # raise_logger("最新区块时间=" + str(latest_eos_block_time) + "时间:" + get_utc_now().strftime(
            #     "%Y-%m-%d %H:%M:%S.%f"), "game_bet_in", "info")
            # raise_logger("时间延迟=" + str(block_delay) + "时间:" + get_utc_now().strftime(
            #     "%Y-%m-%d %H:%M:%S.%f"), "game_bet_in", "info")
            dice_part_in_model = DiceParticipateInModel(
                dice_serial=dice_serial,
                user_id=user_id,
                user_dice=user_dice,
                channel=user_channel_id,
                bet_number=bet_number,
                bet_token=coin_id,
                reward_token=coin_id,
                reward_quantity=bet_number,
                dice_timestamp=dice_time,
                block_no=block_no)
            session.add(dice_part_in_model)
            session.flush()
            # raise_logger("添加dice参与记录成功, id= " + str(dice_part_in_model._id) + "时间:" + get_utc_now().strftime(
            #     "%Y-%m-%d %H:%M:%S.%f"), "game_bet_in", "info")
            # 提交扣款申请
            dice_part_id = dice_part_in_model._id
            result = account_service.do_bet(
                session, user_id, coin_id, bet_number,
                'dice_bet' + str(dice_part_in_model._id), 1, dice_serial,
                user_channel_id)
            if result != 0:
                session.rollback()
                raise_logger("do_bet result" + str(result), "game_bet_in",
                             "info")
            # raise_logger("提交扣款申请成功 " + "时间:" + get_utc_now().strftime(
            #     "%Y-%m-%d %H:%M:%S.%f"), "game_bet_in", "info")
            session.commit()
        return {
            # 'result': True,
            'dice_timestamp':
            timestamp_to_str(dice_time, format_style="%Y-%m-%d %H:%M:%S"),
            'dice_id':
            dice_part_id,
            'dice_serial':
            dice_serial
        }
 def check_dice_sold_out_by_eos(self):
     # raise_logger("sold_out开始" + " 时间:" + get_utc_now().strftime(
     #     "%Y-%m-%d %H:%M:%S.%f"), "game_bet_in", "info")
     with MysqlTools().session_scope() as session:
         account_service = AccountService()
         not_lottery_list = session.query(DiceParticipateInModel). \
             filter(DiceParticipateInModel.dice_result == -1).all()
         if len(not_lottery_list) > 0:
             for not_lottery in not_lottery_list:
                 # raise_logger("需开奖记录id=" + str(not_lottery._id) + " 时间:" + get_utc_now().strftime(
                 #     "%Y-%m-%d %H:%M:%S.%f"), "game_bet_in", "info")
                 lottery_block = not_lottery.block_no
                 lottery_eos_block_info = session.query(SyncEosModel). \
                     filter(SyncEosModel.block_num == lottery_block).first()
                 if lottery_eos_block_info is not None:
                     # raise_logger("找到开奖区块lottery_block" + str(
                     #     lottery_eos_block_info.block_hash) + " 时间:" + get_utc_now().strftime(
                     #     "%Y-%m-%d %H:%M:%S.%f"), "game_bet_in", "info")
                     not_lottery.block_timestamp = lottery_eos_block_info.time_stamp
                     not_lottery.block_hash = lottery_eos_block_info.block_hash
                     dice_result = -1
                     banker_dice = int(not_lottery.block_hash,
                                       16) % 3  # 0石头 1剪刀 2布
                     user_dice = not_lottery.user_dice  # 0石头 1剪刀 2布
                     if banker_dice == user_dice:
                         dice_result = 1  # 0用户胜 1平局 2庄家胜 -1未知
                     else:
                         if banker_dice == 0 and user_dice == 1:
                             dice_result = 2
                         elif banker_dice == 0 and user_dice == 2:
                             dice_result = 0
                         elif banker_dice == 1 and user_dice == 0:
                             dice_result = 0
                         elif banker_dice == 1 and user_dice == 2:
                             dice_result = 2
                         elif banker_dice == 2 and user_dice == 0:
                             dice_result = 2
                         elif banker_dice == 2 and user_dice == 1:
                             dice_result = 0
                     not_lottery.banker_dice = banker_dice
                     not_lottery.dice_result = dice_result
                     session.flush()
                     if dice_result in [0, 1]:
                         reward_quantity = 0
                         dice_config = session.query(DiceConfigModel). \
                             filter(DiceConfigModel.support_token_id == not_lottery.bet_token).first()
                         if dice_config is None:
                             return self.return_error(40022)
                         if dice_result == 0:
                             # 用户获胜 中奖金额为投注金额+奖励金额(投注金额=奖励金额) 扣除手续费
                             reward_quantity = (
                                 not_lottery.reward_quantity +
                                 not_lottery.bet_number) * (
                                     100 - dice_config.handling_fee) / 100
                         elif dice_result == 1:
                             # 平局 中奖金额为投注金额
                             reward_quantity = not_lottery.bet_number
                         result = account_service.do_win(
                             session, not_lottery.user_id,
                             not_lottery.reward_token, reward_quantity,
                             'dice_win' + str(not_lottery._id),
                             not_lottery.user_dice, not_lottery.dice_serial)
                         if isinstance(result, int) is False:
                             raise_logger(
                                 "dice分钱失败" + "user:"******"game_publish_lottery", "info")
                             session.rollback()
                             return False
                         if result != 0:
                             raise_logger(
                                 "dice分钱失败" + "user:"******"game_publish_lottery", "info")
                             session.rollback()
                             return False
             session.commit()
         # raise_logger("sold_out结束" + " 时间:" + get_utc_now().strftime(
         #     "%Y-%m-%d %H:%M:%S.%f"), "game_bet_in", "info")
     return {'result': True}
Exemple #12
0
 def get_coin_type(self):
     with MysqlTools().session_scope() as session:
         coin = session.query(TokenCoinModel).filter(TokenCoinModel.coin_id == self.coin_id).first()
         return coin.coin_name
Exemple #13
0
    def sync_block(self, token_conf, last_net_block_num, last_local_block, address_list, gather_address_list, eth_tx_list):
        confirm_last_block_num = token_conf["confirm_last_block_num"]
        end_listen_block_num = int(last_net_block_num) - int(confirm_last_block_num)
        # 确认起始侦听区块号
        if not last_local_block:
            begin_listen_block_num = end_listen_block_num
        else:
            if end_listen_block_num <= _ZERO:
                raise Exception("last net_block_num less than confirm_last_block_num")
            last_local_block_num = last_local_block["block_no"]
            last_local_block_status = last_local_block["status"]
            begin_listen_block_num = last_local_block_num + _ONE if last_local_block_status else last_local_block_num

        for listen_num in range(begin_listen_block_num, end_listen_block_num + _ONE):
            if self.process_index is not None:
                if listen_num % self.process_count != self.process_index:
                    continue
            self.slog.info("listen block: ", str(listen_num))
            block_info = self.get_eth_block_info(listen_num)
            block_hash = block_info["hash"]
            block_number = block_info["number"]
            transactions = block_info["transactions"]
            tx_model_list = []
            multi_withdraw_record = None
            foreign_gather_record = None
            wallet_eth = None
            with MysqlTools().session_scope() as session:
                for tx in transactions:
                    # 查询交易详情
                    tx_info = self.get_eth_tx_info(tx)
                    if not tx_info:
                        continue
                    tx_info_receipt = self.get_eth_tx_info_receipt(tx)
                    # 处理 块上的交易Tx 是否碰撞 平台发起的交易Tx
                    if tx in eth_tx_list:
                        # 获取实际到账金额 和 手续费
                        listening_value_ether = get_decimal(self.w3.fromWei(tx_info["value"], self.unit) if tx_info["value"] else _ZERO_S, 18)
                        listening_gas_price_ether = get_decimal(self.w3.fromWei(int(tx_info["gasPrice"]), self.unit) if tx_info["gasPrice"] else _ZERO_S, 18)
                        listening_gas_price_used_ether = get_decimal(tx_info_receipt["gasUsed"] if tx_info_receipt["gasUsed"] else _ZERO_S, 18)
                        listening_gas_ether = listening_gas_price_ether * listening_gas_price_used_ether
                        # 如果存在 更改listening 提现侦听表 状态
                        listening_tx = self.update_wallet_eth_tx(session, tx)
                        listening_tx.listen_flag = _ZERO
                        listening_tx.block_no = block_number
                        record_no = listening_tx.record_no
                        # 改流水表 成功
                        withdraw_order_record = self.get_foreign_withdraw_order_record(session, record_no)
                        if not withdraw_order_record:
                            self.slog.error("没有找到withdraw_order_record根据listening_tx.record_no:", record_no)
                            continue
                        withdraw_order_record.withdraw_status = self.withdraw_success
                        withdraw_order_record.confirm_at = get_utc_now()

                        # 计算已花费未上块时消耗的手续费累计,如果没有一般是0
                        withdraw_consume_total_fee = get_decimal(withdraw_order_record.withdraw_consume_total_fee, 18)
                        # 计算预计冻结金额
                        amount_frozen = withdraw_order_record.withdraw_amount
                        # 计算花费完手续费剩余返还给用户的金额
                        withdraw_remain_fee = amount_frozen - listening_value_ether - listening_gas_ether - withdraw_consume_total_fee
                        # 判断 提现类型 用户提现和中奖
                        if withdraw_order_record.withdraw_type in self.account_withdraw_type_list:

                            # 获取 批量提现流水
                            if not multi_withdraw_record:
                                multi_withdraw_record = self.get_foreign_multi_withdraw_order_record(session, withdraw_order_record.relate_flow_no)

                            # 通知 账户成功
                            withdraw_result = _FOUR_S
                            do_withdraw_result = WalletCallbackService.withdraw_notify_callback(withdraw_order_record.req_no, withdraw_order_record.order_no, withdraw_result,
                                                                                                listening_value_ether, listening_gas_ether, withdraw_remain_fee)
                            # 保存 账户处理结果
                            withdraw_order_record.do_withdraw_result = do_withdraw_result

                            # 判断用户系统返回结果 "0"是正确
                            if do_withdraw_result == _ZERO_S:
                                # 加钱 提现流水 单笔
                                withdraw_order_record.withdraw_actual_amount = listening_value_ether
                                withdraw_order_record.withdraw_actual_fee = listening_gas_ether + withdraw_consume_total_fee

                                # 加钱 批量提现流水 累计
                                multi_withdraw_record.verified_amount += listening_value_ether
                                multi_withdraw_record.verified_gas += listening_gas_ether + withdraw_consume_total_fee

                                # 减钱 归集地址 冻结金额
                                wallet_eth = self.get_wallet_eth_gather(session, withdraw_order_record.from_address)
                                wallet_eth.amount_frozen -= amount_frozen
                                wallet_eth.amount += withdraw_remain_fee

                        # 判断 提现类型 普通归集和归集转归集
                        elif withdraw_order_record.withdraw_type in self.gather_withdraw_type_list:

                            # 获取 归集操作流水
                            if not foreign_gather_record:
                                foreign_gather_record = self.get_foreign_gather_record(session, withdraw_order_record.relate_flow_no)

                            # 加钱 提现流水 单笔
                            withdraw_order_record.withdraw_actual_amount = listening_value_ether
                            withdraw_order_record.withdraw_actual_fee = listening_gas_ether + withdraw_consume_total_fee

                            # 加钱 归集流水 累计
                            foreign_gather_record.actual_amount += listening_value_ether
                            foreign_gather_record.actual_fee += listening_gas_ether + withdraw_consume_total_fee

                            # 更新 归集流水 部分成功
                            foreign_gather_record.gather_status = self.withdraw_part_success

                            # 判断 普通归集
                            if withdraw_order_record.withdraw_type == _TWO_S:
                                # 获取 用户地址
                                wallet_eth = self.get_wallet_eth(session, withdraw_order_record.from_address)
                            # 判断 归集转归集
                            elif withdraw_order_record.withdraw_type == _THREE_S:
                                # 获取 归集地址
                                wallet_eth = self.get_wallet_eth_gather(session, withdraw_order_record.from_address)

                            # 减钱 相关地址 冻结金额
                            wallet_eth.amount_frozen -= amount_frozen
                            wallet_eth.amount += withdraw_remain_fee
                        else:
                            # 其他类型 暂不处理
                            pass
                        self.slog.info("listening block_number: ", str(block_number))
                        self.slog.info("listening tx: ", str(tx))
                        self.slog.info("listening amount: ", str(listening_value_ether))
                        self.slog.info("listening gas: ", str(listening_gas_ether))

                    # 处理 块上的每笔交易Tx详情 to_address 是否碰撞 平台的子钱包地址 和 归集账户的地址
                    listening_address = tx_info["to"]
                    check_address_flag = None
                    source_status = None
                    do_recharge_result = ""
                    if listening_address in address_list:
                        check_address_flag = _ZERO
                    elif listening_address in gather_address_list:
                        check_address_flag = _ONE
                    if check_address_flag is not None:
                        listening_value_ether = get_decimal(self.w3.fromWei(tx_info["value"], self.unit) if tx_info["value"] else _ZERO_S, 18)

                        # 检查 有没有记录过这个tx在tx_list_eth流水
                        tx_list_model = session.query(TxListEthModel).filter(TxListEthModel.tx_no == tx).first()
                        if not tx_list_model:
                            tx_id = generate_order_no()
                            # 更新子钱包和归集账户地址的钱
                            wallet_model = self.wallet_model_list[check_address_flag]
                            sub_wallet = session.query(wallet_model).filter(wallet_model.sub_public_address == listening_address).first()
                            if check_address_flag == _ZERO:
                                account_id = sub_wallet.account_id
                                # 通知账户加钱
                                do_recharge_result = WalletCallbackService.recharge_notify_callback(account_id, listening_value_ether, self.coin_id, listening_address, tx_id)
                                if do_recharge_result == _ZERO_S:
                                    # 更新子钱包和归集账户地址的钱
                                    sub_wallet.amount += listening_value_ether
                                source_status = _ZERO_S  # 线上用户地址充值
                            elif check_address_flag == _ONE:
                                if tx not in eth_tx_list:
                                    source_status = _ONE_S  # 线下归集账户充值
                                else:
                                    source_status = _ZERO_S  # 线上普通归集归集转归集
                                sub_wallet.amount += listening_value_ether  # 线下充值或者归集

                            # 增加tx_list记录
                            tx_model = TxListEthModel(
                                tx_id=tx_id,
                                tx_no=tx,
                                block_no=block_number,
                                value=listening_value_ether,
                                address=listening_address,
                                source_status=source_status,
                                do_recharge_result=do_recharge_result
                            )
                            tx_model_list.append(tx_model)
                        if tx not in eth_tx_list:
                            self.slog.info("recharge block_number: ", str(block_number))
                            self.slog.info("recharge tx: ", str(tx))
                            self.slog.info("recharge address: ", str(listening_address))
                            self.slog.info("recharge amount: ", str(listening_value_ether))

                if tx_model_list:
                    session.add_all(tx_model_list)
                # 更新SyncBlockModel本地同步远程节点数据块编号
                if not self.block_num_temp:
                    self.update_wallet_eth_address(session, listen_num, block_hash)

                # 提交事物
                session.commit()
        return True
class TokenSyncLotteryScript(object):
    ec = None
    sync_success = _ONE
    sync_fail = _ZERO
    eos_coin_id = _COIN_ID_EOS
    slog = Slog("token_sync_lottery_script")
    mysql_tool = MysqlTools()
    wait_lottery_dict = {}

    def __init__(self):
        pass

    def work(self):
        # 逻辑: 查找GameGetLotteryBlockInfoEosModel看看是否有未开奖 规则 满额时间点的第60个区块(包含当前时间点的块)
        # 找到未开奖列表,查找时间戳 对应的基础区块号,因为是最新时间,基本上数据库都会没有找到该区块
        # 根据基础区块号,生成 开奖区块 确认区块
        # 如果没有找到对应的基础区块号,根据找到的区块号,往回查询EOSPark(睡1秒),直到找到符合时间戳的区块,规则是 一直大,直到找到小的,小的区块号下一个就是是基础区块
        # 更新 sync_eos表 基础区块
        # 找到已经同步的确认区块,返回去查开奖区块,查询EOSPark,更新开奖区块
        # 更新 sync_eos表 开奖区块
        # 更新 GameGetLotteryBlockInfoEosModel 开奖区块hash 状态完成
        # 调韩梦 通知开奖
        with self.mysql_tool.session_scope() as session:
            lottery_block_info_eos_model_list = session.query(GameGetLotteryBlockInfoEosModel).filter(GameGetLotteryBlockInfoEosModel.status != self.sync_success).all()
            if not lottery_block_info_eos_model_list:
                return True
            for lottery_block_info_eos_model in lottery_block_info_eos_model_list:
                if lottery_block_info_eos_model.base_block_num < _ZERO:
                    base_time_stamp = lottery_block_info_eos_model.base_time_stamp
                    sync_eos_model = session.query(SyncEosModel).filter(SyncEosModel.time_stamp_decimal >= base_time_stamp).order_by(SyncEosModel.block_num.asc()).first()
                    if sync_eos_model:  # 找到基础块
                        base_block_num = sync_eos_model.block_num  # 基础块
                        if sync_eos_model.time_stamp_decimal - base_time_stamp < 0.5:
                            lottery_block = base_block_num + lottery_block_info_eos_model.block_num  # 开奖块
                            confirm_block = lottery_block + lottery_block_info_eos_model.confirm_block_num  # 确认块
                            # 更新开奖块 确认块数据
                            lottery_block_info_eos_model.base_block_num = base_block_num
                            lottery_block_info_eos_model.block_num = lottery_block
                            lottery_block_info_eos_model.confirm_block_num = confirm_block
                        else:  # 基础块时间>0.5 找到的不对
                            right_block_detail = self.find_right_block(base_block_num, base_time_stamp)
                            right_sync_eos_model = session.query(SyncEosModel).filter(SyncEosModel.block_num == right_block_detail["block_num"]).first()
                            if right_sync_eos_model:
                                right_sync_eos_model.block_hash = right_block_detail["id"]
                                right_sync_eos_model.time_stamp = right_block_detail["timestamp"]
                                right_sync_eos_model.time_stamp_decimal = right_block_detail["time_stamp_decimal"]
                                right_sync_eos_model.previous = right_block_detail["previous"]
                                right_sync_eos_model.status = self.sync_success
                            else:
                                sync_eos_model = SyncEosModel(
                                    block_num=right_block_detail["block_num"],
                                    block_hash=right_block_detail["id"],
                                    time_stamp=right_block_detail["timestamp"],
                                    time_stamp_decimal=right_block_detail["time_stamp_decimal"],
                                    previous=right_block_detail["previous"],
                                    status=self.sync_success
                                )
                                session.add(sync_eos_model)
                    else:  # 没有找到基础块数据,
                        # 等待脚本下次执行
                        pass
                else:
                    # 有基础块数据 找确认块数据
                    confirm_block_num = lottery_block_info_eos_model.confirm_block_num
                    lottery_block_num = lottery_block_info_eos_model.block_num
                    confirm_block_model = session.query(SyncEosModel).filter(SyncEosModel.block_num == confirm_block_num).first()
                    lottery_block_model = session.query(SyncEosModel).filter(SyncEosModel.block_num == lottery_block_num).first()
                    game_instance_id = lottery_block_info_eos_model.game_instance_id
                    notice_flag = None
                    node_block_detail_block_hash = None
                    node_block_detail_time_stamp = None
                    if confirm_block_model:
                        node_block_detail = self.find_right_block(lottery_block_num)
                        node_block_detail_block_hash = node_block_detail["id"]
                        node_block_detail_time_stamp = node_block_detail["timestamp"]
                        if lottery_block_model and lottery_block_model.block_hash and lottery_block_model.time_stamp:
                            lottery_block_hash = lottery_block_model.block_hash
                            lottery_time_stamp = lottery_block_model.time_stamp
                            if lottery_block_hash != node_block_detail_block_hash or lottery_time_stamp != node_block_detail_time_stamp:
                                lottery_block_model.block_hash = node_block_detail_block_hash
                                lottery_block_model.time_stamp = node_block_detail_time_stamp
                                lottery_block_model.time_stamp_decimal = node_block_detail["time_stamp_decimal"]
                                lottery_block_model.previous = node_block_detail["previous"]
                        else:
                            # 没有找到同步区块,但是找到了确认区块 或者 没有找到这个块hash和time_stamp
                            if lottery_block_model:  # 有开奖区块,没有块hash或者time_stamp
                                lottery_block_model.block_hash = node_block_detail_block_hash
                                lottery_block_model.time_stamp = node_block_detail_time_stamp
                                lottery_block_model.time_stamp_decimal = node_block_detail["time_stamp_decimal"]
                                lottery_block_model.previous = node_block_detail["previous"]
                            else:
                                sync_eos_model = SyncEosModel(
                                    block_num=lottery_block_num,
                                    block_hash=node_block_detail_block_hash,
                                    time_stamp=node_block_detail_time_stamp,
                                    time_stamp_decimal=node_block_detail["time_stamp_decimal"],
                                    previous=node_block_detail["previous"],
                                    status=self.sync_success
                                )
                                session.add(sync_eos_model)
                        notice_flag = True
                    else:
                        lasted_block_detail = self.composing_right_block()
                        lasted_block_num = lasted_block_detail.get("block_num", "")
                        if lasted_block_num and int(lasted_block_num) >= int(confirm_block_num):
                            node_block_detail = self.composing_right_block(lottery_block_num)
                            node_block_detail_block_hash = node_block_detail.get("id", "")
                            node_block_detail_time_stamp = node_block_detail.get("timestamp", "")
                            if lottery_block_model:  # 有开奖区块,没有块hash或者time_stamp
                                lottery_block_model.block_hash = node_block_detail_block_hash
                                lottery_block_model.time_stamp = node_block_detail_time_stamp
                                lottery_block_model.time_stamp_decimal = node_block_detail["time_stamp_decimal"]
                                lottery_block_model.previous = node_block_detail["previous"]
                            else:
                                sync_eos_model = SyncEosModel(
                                    block_num=lottery_block_num,
                                    block_hash=node_block_detail_block_hash,
                                    time_stamp=node_block_detail_time_stamp,
                                    time_stamp_decimal=node_block_detail["time_stamp_decimal"],
                                    previous=node_block_detail["previous"],
                                    status=self.sync_success
                                )
                                session.add(sync_eos_model)
                            notice_flag = True
                        else:
                            # 还没有同步到确认区块 等待脚本下次执行
                            print("1 record is not the lottery, not find confirm_block_num: " + str(int(confirm_block_num)))
                            print("Wait for the next script loop!")
                    if notice_flag:
                        # 通知韩梦
                        process_res = WalletEosService.lottery_callback(game_instance_id, lottery_block_num, node_block_detail_block_hash, node_block_detail_time_stamp, node_block_detail_time_stamp)
                        lottery_block_info_eos_model.block_hash = node_block_detail_block_hash
                        lottery_block_info_eos_model.time_stamp = node_block_detail_time_stamp
                        lottery_block_info_eos_model.status = process_res
                        print("lottery success, notice Mr Han!!!")
                        print("lottery_block_num: " + str(int(lottery_block_num)))
                        print("lottery_block_hash: " + str(node_block_detail_block_hash))
                        print("lottery_time_stamp: " + str(node_block_detail_time_stamp))
                session.commit()

        return True

    def find_right_block(self, block_num, base_time_stamp=None):
        """
        找到对应的区块,时间戳小于0.5的
        :param block_num:
        :param base_time_stamp:
        :return:
        """
        print("find_right_block args:")
        print("block_num: " + str(int(block_num)))
        if base_time_stamp:
            print("base_time_stamp: " + str(base_time_stamp))
        block_detail = self.composing_right_block(block_num)
        if base_time_stamp:
            base_time_stamp = float(base_time_stamp)
            # 假设一个块间隔生成时间需要0.5秒,也就是1秒2块
            tmp_right_time_stamp = block_detail["time_stamp_decimal"]
            tmp_right_block_num = block_num - (tmp_right_time_stamp - base_time_stamp) // _TWO
            for i in range(3600):
                tmp_block_detail = self.composing_right_block(tmp_right_block_num)
                if tmp_block_detail:
                    print("find tmp_right_block_num: " + str(int(tmp_right_block_num)))
                    print("find tmp_right_time_stamp: " + str(tmp_right_time_stamp))
                    tmp_right_time_stamp = tmp_block_detail["time_stamp_decimal"]
                    if tmp_right_time_stamp >= base_time_stamp:
                        if tmp_right_time_stamp - base_time_stamp > 100:
                            tmp_right_block_num -= (tmp_right_time_stamp - base_time_stamp) // _TWO
                            continue
                        else:
                            if tmp_right_time_stamp - base_time_stamp < 0.5:
                                block_detail = tmp_block_detail
                                print("find right_block_num right!!!!!: " + str(int(tmp_right_block_num)))
                                print("find right_time_stamp right!!!!: " + str(tmp_right_time_stamp))
                                break
                            else:
                                tmp_right_block_num -= _ONE
                    else:
                        if base_time_stamp - tmp_right_time_stamp > 100:
                            tmp_right_block_num -= (base_time_stamp - tmp_right_time_stamp) // _TWO
                            continue
                        else:
                            tmp_right_block_num += _ONE

        return block_detail

    def composing_right_block(self, block_num=None):
        """
        查找并组装正确区块
        :param block_num:
        :return:
        """
        block_detail = {}
        # 如果一个小时都没有找到合适的块,就算了,肯定是其他问题
        for i in range(3600):
            block_detail = self.get_node_block_detail_from_block_num(block_num, ["block_num", "timestamp", "id", "previous"])
            if block_detail:
                right_time_stamp_str = block_detail.get("timestamp")
                right_time_stamp = str_to_timestamp(right_time_stamp_str)
                if right_time_stamp:
                    block_detail["time_stamp_decimal"] = right_time_stamp
                    break
                else:
                    time.sleep(0.5)
        return block_detail

    def get_node_block_detail_from_block_num(self, block_num=None, target_parameter_list=None):
        """
        根据区块号,获取节点详情
        :param block_num:
        :param target_parameter_list:
        :return:
        """
        print("get_node_block_detail_from_block_num")
        print("server local time: " + str(time.time()))
        if self.ec is None:
            self.ec = TokenNodeConfModel.get_eos_node_script(script_unit=_ONE_S)
        if block_num:
            print("block_num: " + str(block_num))
            block_num = int(block_num)
            block_detail = self.ec.http_get_block_detail(block_num)
        else:
            block_detail = self.ec.http_get_latest_block()

        ret_dict = {}
        if block_detail:
            print("timestamp: " + block_detail.get("timestamp", ""))
            if not target_parameter_list:
                return block_detail
            else:
                for i in target_parameter_list:
                    ret_dict[i] = block_detail.get(i, "")
                return ret_dict
        return ret_dict

    def process_game_list(self):
        f_filters = {
            "block_hash": "",
            "status": _ZERO
        }

        with self.mysql_tool.session_scope() as session:
            base_block_num_not_have_model_list = session.query(GameGetLotteryBlockInfoEosModel).filter(GameGetLotteryBlockInfoEosModel.base_block_num < _ZERO).all()
            if base_block_num_not_have_model_list:
                for base_block_num_not_have_model in base_block_num_not_have_model_list:
                    base_time_stamp = base_block_num_not_have_model.base_time_stamp
                    lottery_block_add = base_block_num_not_have_model.block_num
                    confirm_block_add = base_block_num_not_have_model.confirm_block_num
                    base_block = session.query(SyncEosModel).filter(SyncEosModel.time_stamp_decimal >= base_time_stamp).order_by(SyncEosModel.block_num.asc()).first()
                    if base_block and base_block.time_stamp_decimal - base_time_stamp <= _SIXTY:
                        base_block_num = base_block.block_num
                        base_block_num_not_have_model.base_block_num = base_block_num
                        base_block_num_not_have_model.block_num = base_block_num + lottery_block_add
                        base_block_num_not_have_model.confirm_block_num = base_block_num + lottery_block_add + confirm_block_add
                        session.commit()

            wait_lottery_model_list = session.query(GameGetLotteryBlockInfoEosModel).filter_by(**f_filters).filter(GameGetLotteryBlockInfoEosModel.base_block_num > _ZERO).all()
            if wait_lottery_model_list:
                wait_lottery_dict = {}
                wait_lottery_list = []
                for lottery_info_model in wait_lottery_model_list:
                    wait_lottery_dict[str(lottery_info_model.confirm_block_num)] = {
                        "game_instance_id": lottery_info_model.game_instance_id, "block_num": lottery_info_model.block_num}
                    wait_lottery_list.append(lottery_info_model.confirm_block_num)

                sync_eos_model_list = session.query(SyncEosModel).filter(
                    SyncEosModel.block_num.in_(wait_lottery_list), SyncEosModel.status == self.sync_success).all()

                if sync_eos_model_list:
                    for sync_eos_model in sync_eos_model_list:
                        confirm_block_num = sync_eos_model.block_num
                        game_instance_id = wait_lottery_dict[str(confirm_block_num)]["game_instance_id"]
                        block_no = wait_lottery_dict[str(confirm_block_num)]["block_num"]
                        lottery_eos_model = session.query(SyncEosModel).filter(SyncEosModel.block_num == block_no).first()
                        if lottery_eos_model:
                            block_hash = lottery_eos_model.block_hash
                            sync_eos = self.update_sync_eos(session, block_no, block_hash)
                            if sync_eos:
                                block_hash = sync_eos["block_hash"]
                                received_time = timestamp = sync_eos["time_stamp"]
                                TokenSyncLotteryScript.lottery_callback(session, game_instance_id, block_no, block_hash, timestamp, received_time)
                                if str(confirm_block_num) in wait_lottery_dict:
                                    del wait_lottery_dict[str(confirm_block_num)]
                                session.commit()
                self.wait_lottery_dict = wait_lottery_dict
        return True

    def update_sync_eos(self, session, block_num, block_hash):
        """
        开奖时,如果再次查询节点上的该区块,如果hash有变化,说明回滚,取最新区块详情,修改该区块
        :param session:
        :param block_num:
        :param block_hash:
        :return:
        """
        block_detail = self.ec.http_get_block_detail(block_num)
        if block_detail:
            remote_block_hash = block_detail.get("id", "")
            time_stamp = block_detail.get("timestamp", "")
            if remote_block_hash:
                if remote_block_hash != block_hash:
                    sync_eos_model = session.query(SyncEosModel).filter(SyncEosModel.block_num == block_num).first()
                    if sync_eos_model:
                        time_stamp_decimal = get_decimal(str_to_timestamp(time_stamp), digits=3)
                        previous = block_detail.get("previous", "")
                        sync_eos_model.block_hash = remote_block_hash
                        sync_eos_model.time_stamp = time_stamp
                        sync_eos_model.time_stamp_decimal = time_stamp_decimal
                        sync_eos_model.previous = previous
                        sync_eos_model.status = self.sync_success
                        self.slog.info("lottery block_num:", block_num, "lottery block_hash:", remote_block_hash)

                return {
                    "block_hash": remote_block_hash,
                    "time_stamp": time_stamp,
                }
        return {}

    @staticmethod
    def lottery_callback(session, game_instance_id, block_no, block_hash, timestamp, received_time):
        """

        :param session:
        :param game_instance_id:
        :param block_no:
        :param block_hash:
        :param timestamp:
        :param received_time:
        :return:
        """
        process_res = WalletEosService.lottery_callback(game_instance_id, block_no, block_hash, timestamp, received_time)
        session.query(GameGetLotteryBlockInfoEosModel).filter(
            GameGetLotteryBlockInfoEosModel.game_instance_id == game_instance_id).update({
            GameGetLotteryBlockInfoEosModel.block_hash: block_hash,
            GameGetLotteryBlockInfoEosModel.time_stamp: timestamp,
            GameGetLotteryBlockInfoEosModel.status: process_res
        })
        return True
Exemple #15
0
    def game_instance_info_list(self, limit, offset, status='', start_id=None):
        offset = get_offset_by_page(offset, limit)
        result_dict = {
            'limit': limit,
            'offset': offset,
            'count': 0,
            'content': []
        }
        account_service = AccountService()
        with MysqlTools().session_scope() as session:
            if status != '':
                q = session.query(GameDigitalInstanceModel). \
                    order_by(GameDigitalInstanceModel.status.asc(),
                             GameDigitalInstanceModel.created_at.desc(),
                             GameDigitalInstanceModel._id != 0)
                q = q.filter(GameDigitalInstanceModel.status == status)
            else:
                q = session.query(GameDigitalInstanceModel). \
                    order_by(GameDigitalInstanceModel.created_at.desc(),
                             GameDigitalInstanceModel._id != 0)
            record_count = q.count()
            result_dict['count'] = get_page_by_offset(record_count, limit)
            if start_id is not None:
                start_id = str(start_id)
                q = q.filter(GameDigitalInstanceModel._id < start_id)
            query_result = q.limit(limit).offset(offset).all()
            winner = ''
            bet_serial = ''
            bet_number = 0
            # --------------- 即时开 --------------- #
            if status == '':
                ins_instance = session.query(InstantGameInstanceModel). \
                    order_by(InstantGameInstanceModel.created_at.desc()).first()
                if ins_instance is not None:
                    result_dict['content'].append({
                        'id':
                        ins_instance._id,
                        'created_at':
                        str(ins_instance.created_at),
                        'game_serial':
                        ins_instance.game_serial,
                        'game_title':
                        ins_instance.game_title,
                        'progress':
                        0,
                        'remain':
                        0,
                        'bet_token':
                        self.get_coin_name(ins_instance.bet_token),
                        'bet_number':
                        0,
                        'reward_token':
                        self.get_coin_name(ins_instance.reward_token),
                        'reward_quantity':
                        ins_instance.reward_quantity,
                        'support_token':
                        ins_instance.support_token,
                        'status':
                        -1,
                        'lottery_time':
                        str(ins_instance.lottery_time),
                        'winners':
                        '',
                        'bet_serial':
                        '',
                        'game_describe':
                        ins_instance.game_describe,
                        'participation':
                        ins_instance.participation,
                        'merge_id':
                        -1,
                        'merge_list': []
                    })
            # --------------- 即时开end --------------- #
            for i in query_result:
                merge_id = -1
                merges = []
                merge_list = session.query(MergeParticipateInModel). \
                    filter(MergeParticipateInModel.game_instance_id == i._id). \
                    order_by(MergeParticipateInModel.created_at.desc()).limit(3).offset(0).all()
                if len(merge_list) > 0:
                    merge_id = 1
                    for merge in merge_list:
                        initiate_user = account_service.get_inner_user_account_info(
                            session, merge.initiate_user_id)
                        merges.append({
                            'merge_id':
                            merge._id,
                            'name':
                            initiate_user['nick_name'],
                            'portrait':
                            initiate_user['profile_picture']
                        })
                if i.status == 2:
                    winning_record = session.query(WinningRecordModel). \
                        filter(WinningRecordModel.game_instance_id == i._id).first()
                    if winning_record is not None:
                        if winning_record.user_type == 0:
                            account_service = AccountService()
                            user_info = account_service.get_inner_user_account_info(
                                session, winning_record.user_id)
                            winner = user_info['nick_name']
                        elif winning_record.user_type == 1:
                            robot = session.query(RobotAccountModel).filter(
                                RobotAccountModel.user_id ==
                                winning_record.user_id).first()
                            winner = robot.nick_name
                        else:
                            winner = 'X@17Yau8'
                        bet_serial = winning_record.bet_serial
                        merge_id = winning_record.merge_id
                        bet_number = winning_record.bet_number
                progress = 0
                progress = (i.bet_number / i.need) * 100
                if 0 < progress < 1:
                    progress = 1
                if progress > 1:
                    progress = int(progress)

                result_dict['content'].append({
                    'id':
                    i._id,
                    'created_at':
                    str(i.created_at),
                    'game_serial':
                    i.game_serial,
                    'game_title':
                    i.game_title,
                    'progress':
                    progress,
                    'remain':
                    int(i.need - i.bet_number),
                    'bet_token':
                    self.get_coin_name(i.bet_token),
                    'bet_number':
                    bet_number,
                    'reward_token':
                    self.get_coin_name(i.reward_token),
                    'reward_quantity':
                    i.reward_quantity,
                    'support_token':
                    i.support_token,
                    'status':
                    i.status,
                    'lottery_time':
                    str(i.lottery_time),
                    'winners':
                    winner,
                    'bet_serial':
                    bet_serial,
                    'game_describe':
                    i.game_describe,
                    'participation':
                    i.participation,
                    'merge_id':
                    merge_id,
                    'merge_list':
                    merges
                })
        return result_dict
    def dice_sold_out_new(self, dice_id):
        change_type_31 = '31'  # 扣款
        change_type_32 = '32'  # 返还
        change_type_33 = '33'  # 中奖
        reward_quantity = decimal.Decimal(0)
        with MysqlTools().session_scope() as session:
            account_service = AccountService()
            dice_info = session.query(DiceParticipateInModel). \
                filter(DiceParticipateInModel._id == dice_id).first()
            if dice_info is None:
                self.return_error(40021)
            ec = TokenNodeConfModel.get_eos_node_script(script_unit=_THREE_S)
            latest_eos_block_info = ec.http_get_latest_block()
            # print('latest_eos_block_info=-=-=', latest_eos_block_info)
            dice_info.block_no = latest_eos_block_info.get('block_num', None)
            dice_info.block_timestamp = latest_eos_block_info.get(
                'timestamp', None)
            dice_info.block_hash = latest_eos_block_info.get('id', None)
            if dice_info.block_no is None or \
                    dice_info.block_timestamp is None or \
                    dice_info.block_hash is None:
                self.return_error(40024)
            else:
                dice_result = -1
                banker_dice = int(dice_info.block_hash, 16) % 3  # 0石头 1剪刀 2布
                user_dice = dice_info.user_dice  # 0石头 1剪刀 2布
                if banker_dice == user_dice:
                    dice_result = 1  # 0用户胜 1平局 2庄家胜 -1未知
                else:
                    if banker_dice == 0 and user_dice == 1:
                        dice_result = 2
                    elif banker_dice == 0 and user_dice == 2:
                        dice_result = 0
                    elif banker_dice == 1 and user_dice == 0:
                        dice_result = 0
                    elif banker_dice == 1 and user_dice == 2:
                        dice_result = 2
                    elif banker_dice == 2 and user_dice == 0:
                        dice_result = 2
                    elif banker_dice == 2 and user_dice == 1:
                        dice_result = 0
                dice_info.banker_dice = banker_dice
                dice_info.dice_result = dice_result
                # session.flush()
                if dice_result in [0, 1]:
                    change_type = change_type_32
                    dice_config = session.query(DiceConfigModel). \
                        filter(DiceConfigModel.support_token_id == dice_info.bet_token).first()
                    if dice_config is None:
                        return self.return_error(40022)
                    if dice_result == 0:
                        change_type = change_type_33
                        # 用户获胜 中奖金额为投注金额+奖励金额(投注金额=奖励金额) 扣除手续费
                        reward_quantity = (
                            dice_info.reward_quantity + dice_info.bet_number
                        ) * (100 - dice_config.handling_fee) / 100
                        dice_info.reward_quantity = reward_quantity
                    elif dice_result == 1:
                        change_type = change_type_32
                        # 平局 中奖金额为投注金额
                        reward_quantity = dice_info.bet_number
                    result = account_service.do_win(
                        session, dice_info.user_id, dice_info.reward_token,
                        reward_quantity, 'dice_win' + str(dice_info._id),
                        dice_info.user_dice, dice_info.dice_serial,
                        change_type)
                    if isinstance(result, int) is False:
                        raise_logger(
                            "dice分钱失败" + "user:"******"game_publish_lottery", "info")
                        session.rollback()
                        return False
                    if result != 0:
                        raise_logger(
                            "dice分钱失败" + "user:"******"game_publish_lottery", "info")
                        session.rollback()
                        return False
            # ret_info = dice_info
            # print(ret_info)
            session.commit()
            session.refresh(dice_info)
            # session.expunge(dice_info)
        response = {
            'dice_result': dice_info.dice_result,
            'banker_dice': dice_info.banker_dice,
            'user_dice': dice_info.user_dice,
            # 'dice_timestamp': timestamp_to_str(dice_info.dice_timestamp, format_style="%Y-%m-%d %H:%M:%S"),
            'dice_id': str(dice_info._id),
            'dice_serial': dice_info.dice_serial,
            'reward_token': self.get_coin_name(dice_info.reward_token),
            'reward_quantity': decimal_to_str(reward_quantity, 6)
            # 'reward_quantity': decimal_to_str(
            #     str((dice_info.bet_number + dice_info.bet_number) * decimal.Decimal(0.99)), 6)
        }

        if dice_info.reward_token == int(_COIN_ID_USDT):
            response['reward_quantity'] = decimal_to_str(reward_quantity, 4)
        return response
Exemple #17
0
    def indiana_record(self, limit, offset, user_id, start_id=None):
        offset = get_offset_by_page(offset, limit)
        result_dict = {
            'limit': limit,
            'offset': offset,
            'count': 0,
            'content': []
        }
        with MysqlTools().session_scope() as session:
            q = session.query(ParticipateInModel._id,
                              ParticipateInModel.game_instance_id, ParticipateInModel.game_serial,
                              ParticipateInModel.bet_token,
                              (ParticipateInModel.bet_unit * ParticipateInModel.bet_number).label(
                                  'total_bet'),
                              ParticipateInModel.merge_id, ParticipateInModel.created_at,
                              ParticipateInModel.pay_token, ParticipateInModel.pay_number). \
                filter(ParticipateInModel.user_id == user_id). \
                order_by(ParticipateInModel.created_at.desc())
            record_count = q.count()
            result_dict['count'] = get_page_by_offset(record_count, limit)
            if start_id is not None:
                start_id = str(start_id)
                q = q.filter(ParticipateInModel._id < start_id)
            participate_list = q.limit(limit).offset(offset).all()
            for i in participate_list:
                instance_info = session.query(GameDigitalInstanceModel.need, GameDigitalInstanceModel.status,
                                              GameDigitalInstanceModel.bet_token,
                                              GameDigitalInstanceModel.participation). \
                    filter(GameDigitalInstanceModel._id == i.game_instance_id).first()
                if instance_info is None:
                    continue
                total = instance_info.participation
                lower = session.query((func.count(ParticipateInModel._id)).label('lower_users')). \
                    filter(ParticipateInModel.game_instance_id == i.game_instance_id,
                           ParticipateInModel.bet_unit * ParticipateInModel.bet_number < int(i.total_bet)). \
                    first()
                hc = hcf(int(i.total_bet), int(instance_info.need))
                probability = str(int(int(i.total_bet) / hc)) + '/' + str(
                    int(int(instance_info.need) / hc))
                if lower is None:
                    lower = total
                else:
                    lower = lower.lower_users
                if int(i.pay_token) == int(_COIN_ID_EXP):
                    pay_number = int(i.pay_number)
                else:
                    pay_number = decimal_to_str(i.pay_number, 8)
                result_dict['content'].append({
                    'instance_id':
                    i.game_instance_id,
                    'participate_id':
                    i._id,
                    'game_serial':
                    i.game_serial,
                    'bet_token':
                    self.get_coin_name(i.bet_token),
                    'total_bet':
                    int(i.total_bet),
                    'need':
                    instance_info.need,
                    'status':
                    instance_info.status,
                    'need_token':
                    self.get_coin_name(instance_info.bet_token),
                    'probability':
                    probability,
                    'ranking':
                    math.ceil((lower / total) * 100),
                    'merge_id':
                    i.merge_id,
                    'part_in_time':
                    str(i.created_at),
                    "pay_token":
                    self.get_coin_name(i.pay_token),
                    "pay_number":
                    pay_number
                })

        return result_dict
 def __init__(self, *args, **kwargs):
     super().__init__(*args, **kwargs)
     self.mysql_token = MysqlTools(get_about_conf())
     self.coin_id = None
Exemple #19
0
    def indiana_record_new(self, limit, offset, user_id, start_id=None):
        offset = get_offset_by_page(offset, limit)
        result_dict = {
            'limit': limit,
            'offset': offset,
            'count': 0,
            'content': []
        }
        with MysqlTools().session_scope() as session:
            q = session.query(ParticipateInModel._id,
                              ParticipateInModel.game_instance_id, ParticipateInModel.game_serial,
                              ParticipateInModel.bet_token,
                              ParticipateInModel.award_numbers,
                              ParticipateInModel.win_number,
                              (ParticipateInModel.bet_unit * ParticipateInModel.bet_number).label(
                                  'total_bet'),
                              ParticipateInModel.merge_id, ParticipateInModel.created_at,
                              ParticipateInModel.pay_token, ParticipateInModel.pay_number). \
                filter(ParticipateInModel.user_id == user_id). \
                order_by(ParticipateInModel.created_at.desc())
            record_count = q.count()
            result_dict['count'] = get_page_by_offset(record_count, limit)
            if start_id is not None:
                start_id = str(start_id)
                q = q.filter(ParticipateInModel._id < start_id)
            participate_list = q.limit(limit).offset(offset).all()
            for i in participate_list:
                award_numbers_list = i.award_numbers
                if i.game_instance_id == 0:
                    instance_info = session.query(InstantGameInstanceModel.need, InstantGameInstanceModel.status,
                                                  InstantGameInstanceModel.bet_token,
                                                  InstantGameInstanceModel.participation). \
                        filter(InstantGameInstanceModel.game_serial == i.game_serial).first()
                    if instance_info is None:
                        continue
                    if i.win_number in award_numbers_list:
                        is_win = True
                    else:
                        is_win = False
                else:
                    instance_info = session.query(GameDigitalInstanceModel.need, GameDigitalInstanceModel.status,
                                                  GameDigitalInstanceModel._id,
                                                  GameDigitalInstanceModel.bet_token,
                                                  GameDigitalInstanceModel.participation). \
                        filter(GameDigitalInstanceModel._id == i.game_instance_id).first()
                    if instance_info is None:
                        continue
                    if instance_info.status == 2:
                        winning_record = session.query(WinningRecordModel). \
                            filter(WinningRecordModel.game_instance_id == instance_info._id).first()
                        if winning_record.bet_serial in award_numbers_list:
                            is_win = True
                        else:
                            is_win = False
                    else:
                        is_win = False
                if int(i.pay_token) == int(_COIN_ID_EXP):
                    pay_number = int(i.pay_number)
                else:
                    pay_number = decimal_to_str(i.pay_number, 8)
                result_dict['content'].append({
                    'is_win':
                    is_win,
                    'instance_id':
                    i.game_instance_id,
                    'participate_id':
                    i._id,
                    'game_serial':
                    i.game_serial,
                    'bet_token':
                    self.get_coin_name(i.bet_token),
                    'total_bet':
                    int(i.total_bet),
                    # 'need': instance_info.need,
                    'status':
                    instance_info.status,
                    'need_token':
                    self.get_coin_name(instance_info.bet_token),
                    # 'probability': probability,
                    # 'ranking': math.ceil((lower / total) * 100),
                    'merge_id':
                    i.merge_id,
                    'part_in_time':
                    str(i.created_at),
                    "pay_token":
                    self.get_coin_name(i.pay_token),
                    "pay_number":
                    pay_number
                })

        return result_dict
    def get_private_key_from_address(self, args):
        order_no = args["order_no"]
        coin_type = args["type"].upper()
        address = args["address"]
        category = args.get("category", self._normal)

        # 查询coin_id
        with self.mysql_token.session_scope() as session:
            # 查询 token_id
            token = session.query(TokenCoinModel).filter(
                TokenCoinModel.coin_name == coin_type).first()
            if not token:
                self.return_error(90002)
            self.coin_id = token.coin_id

        # 判断地址合法性
        if isinstance(address, str):
            address = [address]
        else:
            if not isinstance(address, list):
                self.return_error(90001)

        # 判断币种类型合法性
        if coin_type not in self.symbol_to_model:
            self.return_error(90002)

        # 判断地址类型合法性
        if category == self._normal:
            model_index = _ONE
            ret = {"category": self._normal}
        elif category == self._gather:
            model_index = _TWO
            ret = {"category": self._gather}
        else:
            self.return_error(90004)
            ret = {}
            model_index = _ZERO

        # 获取对应model
        chain_model = self.symbol_to_model[coin_type][model_index]

        # 地址转成字符串
        address_record = get_str_from_list(address)

        # 查询结果,并记录流水
        with MysqlTools().session_scope() as session:
            record = session.query(RecordPkModel).filter(
                RecordPkModel.order_no == order_no).first()
            if record:
                self.return_error(10008)

            wallets = session.query(chain_model).filter(
                chain_model.sub_public_address.in_(
                    address)).with_for_update().all()
            if not wallets:
                self.return_error(90003)

            for w in wallets:
                public_key_aes = w.acct_public_key_aes
                public_address = w.sub_public_address
                private_key_aes = w.sub_private_key_aes

                if public_key_aes not in ret:
                    ret[public_key_aes] = [{
                        "public_address": public_address,
                        "private_key_aes": private_key_aes,
                    }]
                else:
                    ret[public_key_aes].append({
                        "public_address":
                        public_address,
                        "private_key_aes":
                        private_key_aes,
                    })

            record_pk = RecordPkModel(order_no=order_no,
                                      coin_id=self.coin_id,
                                      address=address_record,
                                      response=json.dumps(ret),
                                      category=category)
            session.add(record_pk)
            session.commit()

        return ret
class WalletService(BaseService):
    symbol_to_token_coin = {
        _BTC: _COIN_ID_BTC,
        _ETH: _COIN_ID_ETH,
        _EOS: _COIN_ID_EOS
    }
    symbol_to_model = {
        _BTC: [
            WalletBtcModel, SecretBtcModel, WalletBtcGatherModel,
            SecretBtcGatherModel
        ],
        _ETH: [
            WalletEthModel, SecretEthModel, WalletEthGatherModel,
            SecretEthGatherModel
        ],
        _EOS: [
            WalletEosModel, SecretEosModel, WalletEosGatherModel,
            SecretEosGatherModel
        ],
    }
    _gather = "gather"
    _normal = "normal"
    interval = _HUNDRED * _ONE

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        wc = get_wallet_config(remove_type=False)
        self.wallet = None
        self.chain_model = None
        self.chain_token_model = None
        self.acct_pub_key_b58_aes = None
        self.coin_id = None
        self.symbol = wc["symbol"].upper()
        self.key = str(wc["key"])
        self.nonce = str(wc["nonce"])
        self.mnemonic = wc["mnemonic"]
        self.passphrase = wc["passphrase"]
        self.category = wc.get("category", self._normal).lower()
        self.mysql_token = MysqlTools(get_about_conf())
        self.mysql_wallet = MysqlTools()

    def wallet_init(self):
        """
        :return:
        """
        if self.symbol not in self.symbol_to_model or self.symbol not in self.symbol_to_token_coin:
            raise Exception("There is no corresponding symbol")
        if self.category == self._normal:
            token_model_index = _ZERO
            secret_model_index = _ONE
        elif self.category == self._gather:
            token_model_index = _TWO
            secret_model_index = _THREE
        else:
            raise Exception("The category does not exist")
        self.chain_token_model = self.symbol_to_model[
            self.symbol][token_model_index]
        self.chain_model = self.symbol_to_model[
            self.symbol][secret_model_index]
        self.wallet = Wallet(symbol=self.symbol)
        self.wallet.init_acct(self.mnemonic, self.passphrase)
        self.acct_pub_key_b58_aes = super_AES(
            self.wallet.get_acct_key()["acct_pub_key_b58"], self.key,
            self.nonce)
        # 查询 token_id
        self.coin_id = self.symbol_to_token_coin[self.symbol]
        with self.mysql_wallet.session_scope() as session:
            # 查询或插入 token_salt
            salt = session.query(TokenSaltModel).filter(
                TokenSaltModel.public_key_aes == self.acct_pub_key_b58_aes,
                TokenSaltModel.coin_id == self.coin_id).first()
            if not salt:
                new_salt = TokenSaltModel(
                    coin_id=self.coin_id,
                    public_key_aes=self.acct_pub_key_b58_aes,
                    key_aes=self.key,
                    nonce_aes=self.nonce)
                session.add(new_salt)
            else:
                if salt.key_aes != self.key or salt.nonce_aes != self.nonce:
                    raise Exception(
                        "Table token_salt contains this key nonce, results already generated cannot be replaced with new key or nonce"
                    )
            session.commit()

    def wallet_generate(self, count):
        """
        生成HD子钱包
        :param count: 生成的子钱包个数, 按index顺序生成, 接续数据库索引
        :return:
        """
        remainder = count % self.interval
        times = count // self.interval + _ONE if remainder else count // self.interval
        for num in range(_ONE, times + _ONE):
            count = self.interval
            if num == times:
                if remainder:
                    count = remainder
            # 获取数据库现有索引
            with self.mysql_wallet.session_scope() as session:
                wallets = session.query(self.chain_model).filter(
                    self.chain_model.acct_public_key_aes ==
                    self.acct_pub_key_b58_aes).with_for_update().order_by(
                        self.chain_model.sub_index.desc(),
                        self.chain_model._id.desc()).first()

                if not wallets:
                    begin = None
                else:
                    begin = int(wallets.sub_index) + _ONE
                print("-" * 20)
                print("The latest index is: " +
                      str(begin - _ONE) if begin else str(_ZERO))

                wallet_list, wallet_token_list = self.chain_model_generate(
                    count, begin)

                with self.mysql_token.session_scope() as session_token:
                    session_token.add_all(wallet_token_list)
                    session_token.commit()

                session.add_all(wallet_list)
                session.commit()
            print("Now we've successfully inserted: " + str(count) + "!!!")
            print("-" * 20)
        return True

    def chain_model_generate(self, count, begin):
        """
        批量生成chain model
        :param count:
        :param begin:
        :return: model list
        """

        sub_key = self.wallet.get_sub_key(count, begin)
        sub_key_aes = {}
        if self.symbol in [_BTC, _ETH]:
            for k, v in sub_key.items():
                sub_key_aes[k] = super_AES(v, self.key, self.nonce)
        elif self.symbol in [_EOS]:
            sub_key_aes = sub_key
        wallet_list = []
        wallet_token_list = []
        for sub_index, index_info in sub_key_aes.items():
            if self.symbol in [_EOS] and self.category == self._gather:
                index_info["sub_private_key"] = super_AES(
                    index_info["sub_private_key"], self.key, self.nonce)
                index_info["sub_address"] = self.mnemonic
            print('  change_index: ' + index_info["change_index"] +
                  " public_address: " + index_info["sub_address"])
            w = self.chain_model(
                sub_index=int(sub_index),
                change_index=index_info["change_index"],
                sub_private_key_aes=index_info["sub_private_key"],
                sub_public_key_aes=index_info["sub_public_key"],
                sub_public_address=index_info["sub_address"],
                acct_public_key_aes=self.acct_pub_key_b58_aes,
                coin_id=self.coin_id)
            w_token = self.chain_token_model(
                sub_index=int(sub_index),
                change_index=index_info["change_index"],
                sub_public_address=index_info["sub_address"],
                acct_public_key_aes=self.acct_pub_key_b58_aes,
                coin_id=self.coin_id)
            wallet_list.append(w)
            wallet_token_list.append(w_token)
        return wallet_list, wallet_token_list

    @staticmethod
    def generate_key_nonce(key, nonce):
        """
        transform origin args type
        :param key: must be origin
        :param nonce:
        :return:
        """
        return {"key": encode_str_hex(key), "nonce": encode_str_hex(nonce)}
Exemple #22
0
def test_mysql():
    with MysqlTools().session_scope() as session:
        yield from asyncio.sleep(10)
        res = session.query(TokenConfModel).first()
        print(res.coid)