예제 #1
0
 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()
         with self.mysql_eos_tool.session_scope() as session_eos:
             with self.mysql_tool.session_scope() as session_select:
                 for block_no_item in range(i, temp_remote_block_num):
                     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)
                     else:
                         time_stamp = temp_insert_block_data.get("timestamp", "")
                         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)
                     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_eos.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()
                     session_eos.commit()
                 except Exception as e:
                     self.slog.error(str(e))
                 print("insert time " + str(time.time() - btime))
     return True
class ParticipateInModel(BaseModel):
    __tablename__ = "participate_in"

    game_instance_id = Column(BigInteger, nullable=False, comment="game实例id")
    template_id = Column(BigInteger, nullable=False, server_default="0", comment="game模版id")
    game_serial = Column(String(64), nullable=False, server_default="", comment="投注期号")
    game_title = Column(String(255), nullable=False, server_default="", comment="夺宝标题")
    bet_token = Column(INTEGER, nullable=False, server_default="0", comment="投注币种")
    release_type = Column(TINYINT, nullable=False, server_default="0", comment="发布方式")

    user_id = Column(String(64), nullable=False, server_default="", comment="用户id")
    nick_name = Column(String(64), nullable=False, server_default="", default="", comment="昵称")
    channel = Column(String(64), nullable=False, server_default="",
                     comment="用户参与渠道")  # pc:1    wap:2   ios:3   android:4     BS:0
    pay_token = Column(INTEGER, nullable=False, server_default="0", comment="支付币种")
    bet_unit = Column(INTEGER, nullable=False, server_default="0", comment="投注单位")  # 表示每一注需要几个投注币
    bet_number = Column(INTEGER, nullable=False, server_default="0", comment="投注数量")
    pay_number = Column(Numeric(36, 18), nullable=False, default=get_decimal('0.000000000000000000'),
                        server_default=str(get_decimal('0.000000000000000000')), comment="支付金额")
    award_numbers = Column(MEDIUMTEXT, comment="获奖号码")
    win_number = Column(String(64), nullable=False, server_default="", comment="中奖号码")
    result = Column(TINYINT, nullable=False, server_default="0", comment="开奖结果")  # 0未中奖 1中奖

    user_type = Column(INTEGER, nullable=False, server_default="0", comment="用户类型")  # 真实用户:0    机器人:1

    chain_status = Column(INTEGER, nullable=False, server_default="0", comment="上链状态")  # 未上链:0    上链:1
    merge_id = Column(BigInteger, nullable=False, server_default="-1", comment="合并购买记录id")

    block_no = Column(INTEGER, nullable=False, server_default="0", comment="第三方区块号")
    received_time = Column(String(128), nullable=False, server_default="", comment="第三方区块hash值不可逆时间")
    bet_hash = Column(String(255), nullable=False, server_default="", comment="第三方区块上链不可逆hash值")

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
예제 #3
0
class RobotConfigRecordModel(BaseModel):
    __tablename__ = "robot_config_record"

    user_id = Column(String(64),
                     comment="用户ID",
                     nullable=False,
                     server_default="")
    nick_name = Column(String(64),
                       nullable=False,
                       server_default="",
                       default="",
                       comment="昵称")

    account_id = Column(String(64),
                        unique=True,
                        nullable=False,
                        server_default="",
                        comment="账户号")
    bet_number = Column(INTEGER,
                        nullable=False,
                        server_default="0",
                        comment="投注数量")
    pay_token = Column(INTEGER,
                       nullable=False,
                       server_default="0",
                       comment="支付币种")
    pay_number = Column(Numeric(36, 18),
                        nullable=False,
                        default=get_decimal('0.000000000000000000'),
                        server_default=str(
                            get_decimal('0.000000000000000000')),
                        comment="支付金额")

    game_instance_id = Column(BigInteger, nullable=False, comment="game实例id")
    game_serial = Column(String(64),
                         nullable=False,
                         server_default="",
                         comment="投注期号")

    bet_plan_time = Column(DateTime,
                           nullable=False,
                           server_default="1970-01-01 00:00:00",
                           comment="设定投注时间")

    bet_status = Column(INTEGER,
                        nullable=False,
                        server_default="0",
                        comment="投注状态 0:待投入 1:已完成 2:作废 3:失败")

    time_stamp = Column(BigInteger,
                        nullable=False,
                        comment="时间戳 和 game config配套")

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.account_id = generate_order_no(k=44)
예제 #4
0
    def dice_chip_in_new(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()
            dice_time = get_timestamp()
            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)
            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")
            session.commit()
        return {
            '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
        }
class ForeignMultiWithdrawRecordModel(BaseModel):
    __tablename__ = "foreign_multi_withdraw_record"

    record_id = Column(String(32),
                       unique=True,
                       nullable=False,
                       server_default="",
                       default="",
                       comment="提现记录id")
    coin_id = Column(String(128),
                     nullable=False,
                     server_default="",
                     comment="货币id")
    from_address = Column(String(255),
                          nullable=False,
                          server_default="",
                          comment="出款地址")
    amount = Column(Numeric(36, 18),
                    default=get_decimal('0', 18),
                    nullable=False,
                    server_default="0.000000000000000000",
                    comment="提现总金额(含手续费)")
    amount_change = Column(Numeric(36, 18),
                           default=get_decimal('0', 18),
                           nullable=False,
                           server_default="0.000000000000000000",
                           comment="找零金额")
    gas = Column(Numeric(36, 18),
                 default=get_decimal('0', 18),
                 nullable=False,
                 server_default="0.000000000000000000",
                 comment="提现总手续费")
    verified_amount = Column(Numeric(36, 18),
                             default=get_decimal('0', 18),
                             nullable=False,
                             server_default="0.000000000000000000",
                             comment="已经验证的 提现总金额里的数额")
    verified_gas = Column(Numeric(36, 18),
                          default=get_decimal('0', 18),
                          nullable=False,
                          server_default="0.000000000000000000",
                          comment="已经验证的 提现总手续费的数额")
    withdraw_status = Column(
        String(8),
        nullable=False,
        server_default="0",
        comment="提现状态: 0-未交易, 1-提现中, 2-提现成功, 3-提现失败, 4-交易失败, 5-部分提现成功, 6-部分交易成功"
    )
    process_record = Column(TEXT, comment="操作报错 业务不合法 交易处理报错等等 记录")

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.record_id = generate_order_no()
class WalletBtcGatherModel(BaseModel):
    __tablename__ = "wallet_btc_gather"
    sub_index = Column(BigInteger, nullable=False, comment="归集账户 子钱包索引")
    sub_public_address = Column(String(255),
                                unique=True,
                                nullable=False,
                                server_default="",
                                comment="归集账户 子地址")
    change_index = Column(String(255),
                          nullable=False,
                          server_default="",
                          comment="归集账户 change index")
    acct_public_key_aes = Column(String(255),
                                 nullable=False,
                                 server_default="",
                                 comment="归集账户 主公钥AES加密防止以后有多个助记词生成主秘钥同时使用")
    coin_id = Column(String(128),
                     nullable=False,
                     server_default="",
                     comment="归集账户 货币id")
    account_id = Column(String(64),
                        nullable=False,
                        server_default="",
                        comment="归集账户 主账户ID")
    status = Column(TINYINT(1),
                    nullable=False,
                    server_default="1",
                    comment="归集账户 状态")
    amount = Column(Numeric(21, 18),
                    default=get_decimal('0', 18),
                    nullable=False,
                    server_default="0.000000000000000000",
                    comment="可用余额")
    amount_change = Column(Numeric(21, 18),
                           default=get_decimal('0', 18),
                           nullable=False,
                           server_default="0.000000000000000000",
                           comment="待找零金额")
    amount_frozen = Column(Numeric(21, 18),
                           default=get_decimal('0', 18),
                           nullable=False,
                           server_default="0.000000000000000000",
                           comment="已支付未确认到账(含手续费)")
    desc = Column(String(255),
                  nullable=False,
                  server_default="",
                  comment="归集账户 描述")

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
예제 #7
0
class WalletBtcModel(BaseModel):
    __tablename__ = "wallet_btc"
    sub_index = Column(BigInteger, nullable=False, comment="子钱包索引")
    sub_public_address = Column(String(255), unique=True, nullable=False, server_default="", comment="子地址")
    change_index = Column(String(255), nullable=False, server_default="", comment="change index")
    acct_public_key_aes = Column(String(255), nullable=False, server_default="", comment="主公钥AES加密防止以后有多个助记词生成主秘钥同时使用")
    coin_id = Column(String(128), nullable=False, server_default="", comment="货币id")
    account_id = Column(String(64), nullable=False, server_default="", comment="主账户ID")
    status = Column(TINYINT(1), nullable=False, server_default="0", comment="如果用户有多个地址,标记正使用地址的启用状态: 0-未启用, 1-启用")
    amount = Column(Numeric(36, 18), default=get_decimal('0', 18), nullable=False, server_default="0.000000000000000000", comment="可用余额")
    amount_change = Column(Numeric(36, 18), default=get_decimal('0', 18), nullable=False, server_default="0.000000000000000000", comment="待找零金额")
    amount_frozen = Column(Numeric(36, 18), default=get_decimal('0', 18), nullable=False, server_default="0.000000000000000000", comment="已支付未确认到账")

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
    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 {}
예제 #9
0
class ForeignGatherRecordModel(BaseModel):
    __tablename__ = "foreign_gather_record"

    record_id = Column(String(32),
                       unique=True,
                       nullable=False,
                       server_default="",
                       default="",
                       comment="归集记录id")
    coin_id = Column(String(128),
                     nullable=False,
                     server_default="",
                     comment="货币id")
    public_address = Column(String(255),
                            nullable=False,
                            server_default="",
                            comment="归集账户地址")
    conditions = Column(String(255),
                        nullable=False,
                        server_default="",
                        comment="归集条件")
    purpose_amount = Column(Numeric(36, 18),
                            default=get_decimal('0', 18),
                            nullable=False,
                            server_default="0.000000000000000000",
                            comment="归集计算出的 目标金额(含手续费)")
    actual_amount = Column(Numeric(36, 18),
                           default=get_decimal('0', 18),
                           nullable=False,
                           server_default="0.000000000000000000",
                           comment="已上链 实际金额 累计")
    actual_fee = Column(Numeric(36, 18),
                        default=get_decimal('0', 18),
                        nullable=False,
                        server_default="0.000000000000000000",
                        comment="已上链 实际手续费 累计")
    gather_status = Column(
        String(8),
        nullable=False,
        server_default="0",
        comment="归集状态: 0-未归集, 1-归集中, 2-归集成功, 3-归集失败, 4-交易失败, 5-部分归集成功, 6-部分交易成功"
    )
    process_record = Column(TEXT, comment="操作报错 业务不合法 交易处理报错等等 记录")

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.record_id = generate_order_no()
class DiceParticipateInModel(BaseModel):
    __tablename__ = "dice_participate_in"

    dice_serial = Column(String(64), unique=True, nullable=False, server_default="", comment="对局编号")
    user_id = Column(String(64), nullable=False, server_default="", comment="参与用户id")
    user_dice = Column(TINYINT, nullable=False, server_default="-1", comment="用户出的是什么")  # 0石头 1剪刀 2布
    banker_dice = Column(TINYINT, nullable=False, server_default="-1", comment="庄家出的是什么")  # 0石头 1剪刀 2布
    channel = Column(String(64), nullable=False, server_default="", comment="用户参与渠道")  # pc:1 wap:2 ios:3 android:4 BS:0
    bet_number = Column(Numeric(21, 4), nullable=False, default=get_decimal('0.0000'),
                        server_default=str(get_decimal('0.0000')), comment="投注数量")
    bet_token = Column(INTEGER, nullable=False, server_default="0", comment="投注币种id")
    reward_token = Column(INTEGER, nullable=False, server_default="0", comment="奖励币种id")
    reward_quantity = Column(Numeric(21, 4), nullable=False, default=get_decimal('0.0000'),
                             server_default=str(get_decimal('0.0000')), comment="奖励数量")
    dice_result = Column(TINYINT, nullable=False, server_default="-1", comment="对局结果")  # 0用户胜 1平局 2庄家胜 -1未知
    dice_timestamp = Column(String(255), nullable=False, server_default="0000-00-00T00:00:00.000", comment="对局时间")
    block_timestamp = Column(String(255), nullable=False, server_default="0000-00-00T00:00:00.000", comment="出块时间")
    block_no = Column(INTEGER, nullable=False, server_default="0", comment="开奖区块号 高度")
    block_hash = Column(String(64), nullable=False, server_default="", comment="开奖区块hash")

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
class OperationalActivitiesModel(BaseModel):
    __tablename__ = "operational_activities"

    user_id = Column(String(64), comment="用户ID", nullable=False,
                     server_default="")
    operational_activities_id = Column(String(128), comment="运营活动ID",
                                       nullable=False, server_default="")
    operational_activities_name = Column(String(128), comment="运营活动简称",
                                         nullable=False, server_default="")
    labels = Column(TEXT, comment="标签")

    amount = Column(Numeric(16, 2), default=get_decimal('0', 18),
                    nullable=False, server_default="0.00", comment="奖励金额")

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
예제 #12
0
class TokenConfModel(BaseModel):
    __tablename__ = "token_conf"
    coin_id = Column(String(128),
                     unique=True,
                     nullable=False,
                     server_default="",
                     comment="货币id")
    confirm_last_block_num = Column(String(8),
                                    nullable=False,
                                    server_default="",
                                    comment="确认最后区块数")
    confirm_last_err_days = Column(String(8),
                                   nullable=False,
                                   server_default="",
                                   comment="确认最后提现失败天数")
    withdraw_fee = Column(Numeric(36, 18),
                          default=get_decimal('0', 18),
                          nullable=False,
                          server_default="0.000000000000000000",
                          comment="归集手续费单价/kb")
    gas_lag = Column(Numeric(36, 18),
                     default=get_decimal('0', 18),
                     nullable=False,
                     server_default="0.000000000000000000",
                     comment="app用户体现手续费单价-慢")
    gas_routine = Column(Numeric(36, 18),
                         default=get_decimal('0', 18),
                         nullable=False,
                         server_default="0.000000000000000000",
                         comment="中")
    gas_prior = Column(Numeric(36, 18),
                       default=get_decimal('0', 18),
                       nullable=False,
                       server_default="0.000000000000000000",
                       comment="快")
    gas_limit = Column(Integer,
                       nullable=False,
                       server_default="1",
                       comment="系数:限制可花费gas总量 最多可以是多少个gas price")
    gather_gas = Column(Numeric(36, 18),
                        default=get_decimal('0', 18),
                        nullable=False,
                        server_default="0.000000000000000000",
                        comment="归集 计算的最低手续费")
    gather_minimum_amount = Column(Numeric(36, 18),
                                   default=get_decimal('0', 18),
                                   nullable=False,
                                   server_default="0.000000000000000000",
                                   comment="归集 最小可归集金额")

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
예제 #13
0
class DiceConfigModel(BaseModel):
    __tablename__ = "dice_config"

    support_token_id = Column(INTEGER,
                              nullable=False,
                              server_default="-1",
                              comment="支持币种id")
    support_token_name = Column(String(64),
                                nullable=False,
                                server_default="",
                                comment="支持币种name")
    default_bet_volume = Column(Numeric(21, 4),
                                nullable=False,
                                default=get_decimal('0.0000'),
                                server_default=str(get_decimal('0.0000')),
                                comment="默认投注量")
    lower_bet_volume = Column(Numeric(21, 4),
                              nullable=False,
                              default=get_decimal('0.0000'),
                              server_default=str(get_decimal('0.0000')),
                              comment="投注量下限")
    ceiling_bet_volume = Column(Numeric(21, 4),
                                nullable=False,
                                default=get_decimal('0.0000'),
                                server_default=str(get_decimal('0.0000')),
                                comment="投注量上限")
    handling_fee = Column(INTEGER,
                          nullable=False,
                          server_default="0",
                          comment="手续费率")
    status = Column(TINYINT,
                    nullable=False,
                    server_default="0",
                    comment="支持币种状态")  # 0不可用  1可用

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
class AccountRechargeRecordModel(BaseModel):
    __tablename__ = "account_recharge_record"

    status_1 = '1'  # 进行中
    status_2 = '2'  # 成功
    status_3 = '3'  # 失败

    account_recharge_record_id = Column(String(32),
                                        unique=True,
                                        nullable=False,
                                        server_default="",
                                        default="",
                                        comment="记录id")
    account_id = Column(String(64),
                        nullable=False,
                        server_default="",
                        default="",
                        comment="账户号")
    account_change_record_id = Column(String(64),
                                      nullable=False,
                                      server_default="",
                                      default="",
                                      comment="账户变换记录id")
    user_id = Column(String(64),
                     comment="用户ID",
                     nullable=False,
                     server_default="")
    token_address = Column(String(255),
                           nullable=False,
                           server_default="",
                           default="",
                           comment="我方收款地址")
    memo = Column(String(512),
                  nullable=False,
                  server_default="",
                  default="",
                  comment="memo")
    receive_token = Column(Numeric(36, 18),
                           nullable=False,
                           default=get_decimal('0.000000000000000000'),
                           server_default=str(
                               get_decimal('0.000000000000000000')),
                           comment="应到账token,单位:eth")
    transaction_id = Column(String(128),
                            nullable=False,
                            server_default="",
                            default="",
                            comment="到账交易号")
    token_id = Column(String(255),
                      nullable=False,
                      server_default="",
                      default="",
                      comment="货币名称BTC、ETH、ETC、EOS……")
    status = Column(TINYINT(1),
                    nullable=False,
                    server_default=status_1,
                    default=status_1,
                    comment="状态")
    begin_time = Column(DateTime,
                        nullable=False,
                        server_default="0000-00-00 00:00:00",
                        comment="开始时间")
    finish_time = Column(DateTime,
                         nullable=False,
                         server_default="0000-00-00 00:00:00",
                         comment="完成时间")

    # 记录此次操作的账户状态
    balance = Column(Numeric(36, 18),
                     nullable=False,
                     default=get_decimal('0.000000000000000000'),
                     server_default=str(get_decimal('0.000000000000000000')),
                     comment='余额')
    frozon_amount = Column(Numeric(36, 18),
                           nullable=False,
                           default=get_decimal('0.000000000000000000'),
                           server_default=str(
                               get_decimal('0.000000000000000000')),
                           comment='冻结金额')
    investment_amount = Column(Numeric(36, 18),
                               nullable=False,
                               default=get_decimal('0.000000000000000000'),
                               server_default=str(
                                   get_decimal('0.000000000000000000')),
                               comment='已投金额')
    total_recharge = Column(Numeric(36, 18),
                            nullable=False,
                            default=get_decimal('0.000000000000000000'),
                            server_default=str(
                                get_decimal('0.000000000000000000')),
                            comment='累计充值')
    total_withdraw = Column(Numeric(36, 18),
                            nullable=False,
                            default=get_decimal('0.000000000000000000'),
                            server_default=str(
                                get_decimal('0.000000000000000000')),
                            comment='累计提现')
    total_withdraw_fee = Column(Numeric(36, 18),
                                nullable=False,
                                default=get_decimal('0.000000000000000000'),
                                server_default=str(
                                    get_decimal('0.000000000000000000')),
                                comment='累计提现手续费')
    source = Column(String(64),
                    nullable=False,
                    server_default="",
                    comment="资金来源")

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.account_recharge_record_id = generate_order_no()
예제 #15
0
    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 process_notify_and_insert(self, account_related_trx_info_dict, account_related_trx_info_withdraw_dict):
        # tx_list_eos_model_list = []
        if not self.wallet_callback:
            self.wallet_callback = WalletCallbackService()

        with self.mysql_tool.session_scope() as session:
            # 提现手续费
            withdraw_actual_fee = 0.02
            token_conf_model = session.query(TokenConfModel).filter(TokenConfModel.coin_id == self.eos_coin_id).first()
            if token_conf_model:
                withdraw_actual_fee = token_conf_model.withdraw_fee
            # 充值
            for trx_id, trx_info in account_related_trx_info_dict.items():
                transaction_id = generate_order_no()
                sub_public_address = trx_info["address"]
                token_amount = get_decimal(trx_info["quantity"], digits=_TEN)
                do_recharge_result = ""
                wallet_eos_model = session.query(WalletEosModel).filter(WalletEosModel.sub_public_address == sub_public_address).with_for_update().first()
                wallet_eos_gather_model = session.query(WalletEosGatherModel).filter(WalletEosGatherModel.sub_public_address == self.eos_gather_address).with_for_update().first()
                if wallet_eos_model:
                    # 加钱 给 账户钱包
                    wallet_eos_model.amount += token_amount
                    wallet_eos_gather_model.amount += token_amount
                    # 通知 账户模块
                    account_id = wallet_eos_model.account_id
                    do_recharge_result = self.wallet_callback.recharge_notify_callback(account_id, token_amount, self.eos_coin_id, sub_public_address, transaction_id)
                    # 存充值记录表
                tmp_tx_list_eos_model = TxListEosModel(
                    tx_id=transaction_id,
                    tx_no=trx_id,
                    block_no=trx_info["block_num"],
                    value=token_amount,
                    address=sub_public_address,
                    sender=trx_info["sender"],
                    do_recharge_result=do_recharge_result,
                )
                session.add(tmp_tx_list_eos_model)
                session.commit()
            # 提现
            for withdraw_trx_id, withdraw_trx_info in account_related_trx_info_withdraw_dict.items():
                withdraw_actual_amount = get_decimal(withdraw_trx_info["quantity"], digits=_TEN)
                foreign_withdraw_model = session.query(ForeignWithdrawOrderRecordModel).filter(ForeignWithdrawOrderRecordModel.order_no == withdraw_trx_info["record_no"]).first()
                if foreign_withdraw_model:
                    account_id = foreign_withdraw_model.account_id
                    order_no = foreign_withdraw_model.order_no
                    req_no = foreign_withdraw_model.req_no
                    withdraw_result = self.withdraw_offline_success if withdraw_trx_info["source_status"] == _ONE_S else self.withdraw_online_success
                    # 通知
                    do_withdraw_result = self.wallet_callback.withdraw_notify_callback(req_no, order_no, withdraw_result, withdraw_actual_amount, withdraw_actual_fee)
                    # 更新提现状态
                    foreign_withdraw_model.withdraw_actual_amount = withdraw_actual_amount
                    foreign_withdraw_model.withdraw_actual_fee = withdraw_actual_fee
                    foreign_withdraw_model.withdraw_status = self.withdraw_success
                    foreign_withdraw_model.do_withdraw_result = do_withdraw_result
                    # 修改冻结金额
                    wallet_eos_model = session.query(WalletEosModel).filter(WalletEosModel.account_id == account_id).with_for_update().first()
                    wallet_eos_gather_model = session.query(WalletEosGatherModel).filter(WalletEosGatherModel.sub_public_address == self.eos_gather_address).with_for_update().first()
                    if wallet_eos_model:
                        amount_frozen = withdraw_actual_amount + withdraw_actual_fee
                        wallet_eos_model.amount_frozen -= amount_frozen
                        wallet_eos_gather_model.amount_frozen -= amount_frozen
                        wallet_eos_gather_model.amount += withdraw_actual_fee
                    else:
                        self.slog.error("withdraw not has WalletEosModel by ForeignWithdrawOrderRecordModel.account_id: " + str(account_id))
                else:
                    self.slog.error("withdraw not has ForeignWithdrawOrderRecordModel by TxListeningEosModel.record_no: " + str(withdraw_trx_info["record_no"]))

                # 更新提现记录表侦听状态
                tx_listening_eos_model = session.query(TxListeningEosModel).filter(TxListeningEosModel.order_no == withdraw_trx_info["order_no"]).first()
                if tx_listening_eos_model:
                    tx_listening_eos_model.block_no = withdraw_trx_info["block_num"]
                    tx_listening_eos_model.listen_flag = _ZERO
                    tx_listening_eos_model.memo = withdraw_trx_info["memo"]
                else:
                    self.slog.error("withdraw not has TxListeningEosModel by TxListeningEosModel.order_no: " + str(withdraw_trx_info["order_no"]))
                session.commit()
예제 #17
0
    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)
        }
class UserAccountTokenModel(BaseModel):
    __tablename__ = "user_account_token"

    status_on = '1'  # 在用
    status_off = '0'  # 注销

    account_token_id = Column(String(64),
                              unique=True,
                              nullable=False,
                              server_default="",
                              comment="本表主键")
    account_id = Column(String(64),
                        nullable=False,
                        server_default="",
                        comment="账户号")
    user_id = Column(String(64),
                     comment="用户ID",
                     nullable=False,
                     server_default="")
    token_id = Column(String(255),
                      nullable=False,
                      server_default="",
                      comment="货币名称BTC、ETH、ETC、EOS……")

    # --------------------------------------------------
    # 公式是用来对账的,因此实际代码计算的是有严禁用这个公式
    # 充值 - 提现 - 手续费 - 冻结金额 = 余额 + 已投金额
    # --------------------------------------------------
    total_recharge = Column(Numeric(36, 18),
                            nullable=False,
                            default=get_decimal('0.000000000000000000'),
                            server_default=str(
                                get_decimal('0.000000000000000000')),
                            comment='累计充值')
    total_withdraw = Column(Numeric(36, 18),
                            nullable=False,
                            default=get_decimal('0.000000000000000000'),
                            server_default=str(
                                get_decimal('0.000000000000000000')),
                            comment='累计提现')
    total_withdraw_fee = Column(Numeric(36, 18),
                                nullable=False,
                                default=get_decimal('0.000000000000000000'),
                                server_default=str(
                                    get_decimal('0.000000000000000000')),
                                comment='累计提现手续费')

    balance = Column(Numeric(36, 18),
                     nullable=False,
                     default=get_decimal('0.000000000000000000'),
                     server_default=str(get_decimal('0.000000000000000000')),
                     comment='余额')
    frozon_amount = Column(Numeric(36, 18),
                           nullable=False,
                           default=get_decimal('0.000000000000000000'),
                           server_default=str(
                               get_decimal('0.000000000000000000')),
                           comment='冻结金额')
    investment_amount = Column(Numeric(36, 18),
                               nullable=False,
                               default=get_decimal('0.000000000000000000'),
                               server_default=str(
                                   get_decimal('0.000000000000000000')),
                               comment='已投金额')
    # 用户充值地址
    sub_public_address = Column(String(255),
                                nullable=False,
                                server_default="",
                                comment="子地址")
    memo = Column(String(512),
                  nullable=False,
                  server_default="",
                  comment="memo 信息")

    # 状态
    status = Column(TINYINT(1),
                    nullable=False,
                    server_default=str(status_on),
                    comment="状态 0)注销 1)在用")

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.account_token_id = generate_order_no(k=44)

    def recharge(self, amount):
        # 充值
        if amount < 0:
            return False
        if self.total_recharge is None:
            self.total_recharge = amount
        else:
            self.total_recharge += amount

        if self.balance is None:
            self.balance = amount
        else:
            self.balance += amount
        return True

    def apply_withdraw(self, amount, fee):
        # 提现暂时冻结资产
        if amount < 0:
            return False
        if fee < 0:
            return False
        all_amount = amount + fee
        # 转账费用从转账金额中扣除
        if self.balance < all_amount:
            return False
        self.balance -= all_amount
        self.frozon_amount += all_amount
        return True

    def bet(self, amount):
        # 下注
        if amount < 0:
            return False
        if self.balance < amount:
            return False
        self.balance -= amount
        self.investment_amount += amount
        return True

    def cancel_bet(self, amount):
        # 取消下注
        if amount < 0:
            return False
        if self.investment_amount < amount:
            return False
        self.balance += amount
        self.investment_amount -= amount
        return True

    def do_withdraw(self, amount, fee, return_balance=0):
        # 提现实施
        if amount < 0:
            return False
        if fee < 0:
            return False
        if return_balance < 0:
            return False
        all_amount = amount + fee + return_balance
        if self.frozon_amount < all_amount:
            return False
        self.frozon_amount -= all_amount
        self.total_withdraw += amount
        self.total_withdraw_fee += fee
        self.balance += return_balance
        return True

    def increase_amount(self, amount):
        # 系统inr(如下注后赢币)
        if amount < 0:
            return False
        self.balance += amount
        return True

    def refuse_withdraw(self, amount, fee, return_balance=0):
        # 提现失败系统反还
        if amount < 0:
            return False
        if fee < 0:
            return False
        if return_balance < 0:
            return False
        all_amount = amount + fee + return_balance
        if self.frozon_amount < all_amount:
            return False
        self.frozon_amount -= all_amount
        self.balance += all_amount
        return True
예제 #19
0
    def bet_in(self, dic):
        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("conin_id", "")  # 投入币种id
        bet_amount = dic.get("bet_amount", "")  # 投注数量
        merge_id = dic.get("merge_id", -1)  # 合并投注id
        # transaction_password = dic.get("transaction_password", "")  # 交易密码

        with MysqlTools().session_scope() as session:
            # 查询项目
            model = session.query(GameDigitalInstanceModel).filter(
                GameDigitalInstanceModel._id == id).with_for_update().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)

            # 查询币价 币种实际需要金额
            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, id)
                instance_limit = limit['instance_limit']
                user_limit = limit['user_limit']
                if user_limit > 10 - int(bet_amount):
                    self.return_error(60017)
                if instance_limit >= exp:
                    self.return_error(60016)

            # 查询用户资产
            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)

            # 验证交易密码
            # if account_service.check_pay_password(user_id, transaction_password) is False:
            #     return self.return_error(35024)
            # raise_logger("begin", "game_bet_in", "info")
            # 获取下注编号
            game_numbers = session.query(GameNumbersSetModel).filter(
                GameNumbersSetModel.game_serial ==
                model.game_serial).with_for_update().all()
            numbers = []
            for num in game_numbers:
                numbers.append(num.number)
            numbers = random.sample(numbers, int(bet_amount))
            # raise_logger("get game_numbers", "game_bet_in", "info")
            if isinstance(numbers, list):
                nick_name = account_service.get_inner_user_account_info(
                    session, user_id).get("nick_name")
                try:
                    # 添加参与记录
                    participate_in_model = ParticipateInModel(
                        game_instance_id=model._id,
                        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=merge_id)
                    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)
                    # raise_logger("do_bet success", "game_bet_in", "info")
                    if isinstance(result, int):
                        if result == 0:
                            # 修改项目状态
                            game_service = GameService()
                            # raise_logger("modifyDigitalInstance begin", "game_bet_in", "info")
                            if game_service.modifyDigitalInstance(
                                    model, {
                                        "game_id": id,
                                        "add_bet_number": int(bet_amount),
                                        "full_load_time":
                                        participate_in_model.created_at,
                                        "add_people": 1
                                    }) is False:
                                session.rollback()
                                raise_logger("modifyDigitalInstance err",
                                             "game_bet_in", "info")
                                return self.return_error(80005)
                            # raise_logger("modifyDigitalInstance succ", "game_bet_in", "info")
                            try:
                                created_at_str = str(
                                    participate_in_model.created_at)
                                update_at_str = str(
                                    participate_in_model.update_at)
                                deleted_at_str = str(
                                    participate_in_model.deleted_at)
                                deleted_str = str(participate_in_model.deleted)
                                if BlockChainInfoService(
                                ).insert_block_chain_info(
                                        user_id,
                                        participate_in_model.game_instance_id,
                                        1,
                                    {
                                        "id":
                                        participate_in_model._id,
                                        "created_at":
                                        created_at_str[0:19],
                                        "update_at":
                                        update_at_str[0:19],
                                        "deleted_at":
                                        deleted_at_str[0:19],
                                        "deleted":
                                        deleted_str[0:19],
                                        "game_instance_id":
                                        str(participate_in_model.
                                            game_instance_id),
                                        "template_id":
                                        participate_in_model.template_id,
                                        "game_serial":
                                        participate_in_model.game_serial,
                                        "bet_token":
                                        participate_in_model.bet_token,
                                        "user_id":
                                        participate_in_model.user_id,
                                        "nick_name":
                                        participate_in_model.nick_name,
                                        "channel":
                                        participate_in_model.channel,
                                        "pay_token":
                                        participate_in_model.pay_token,
                                        "bet_number":
                                        participate_in_model.bet_number,
                                        "pay_number":
                                        str(participate_in_model.pay_number),
                                        "award_numbers":
                                        participate_in_model.award_numbers,
                                        "user_type":
                                        participate_in_model.user_type,
                                    }):
                                    participate_in_model.chain_status = 1
                                    # raise_logger("insert_block succ", "game_bet_in", "info")
                                else:
                                    raise_logger("insert_block err",
                                                 "game_bet_in", "info")
                            except Exception as e:
                                session.rollback()
                                raise_logger(e, "game_bet_in", "info")
                            # raise_logger("pri del GameNumbersSetModel", "game_bet_in", "info")
                            for i in numbers:
                                # raise_logger("pri del GameNumbersSetModel", "game_bet_in", "info")
                                # game_number_filters = {"game_serial": model.game_serial, "number": i}
                                session.query(GameNumbersSetModel). \
                                    filter(GameNumbersSetModel.game_serial == model.game_serial,
                                           GameNumbersSetModel.number == i).delete()
                                # number_filter.time_stamp = 1
                                # session.delete(num_filters)
                            # raise_logger("GameNumbersSetModel delete succ", "game_bet_in", "info")

                            # # 检测游戏是否售罄需要申请开奖
                            # instance = session.query(GameDigitalInstanceModel).filter(
                            #     GameDigitalInstanceModel._id == id).first()
                            if int(model.status) == 1:
                                add_result = WalletEosService().lottery_adduce(
                                    id, get_timestamp(model.full_load_time))
                                if not add_result:
                                    raise_logger("lottery_adduce fail",
                                                 "game_bet_in", "info")

                            session.commit()
                            # raise_logger("commit succ", "game_bet_in", "info")
                            try:
                                # # 提交验证是否需要上线新项目
                                game_service.automatic_release(
                                    session, model.template_id)
                            except Exception as e:
                                raise_logger(e, "game_bet_in", "info")

                            can_merge = False
                            if int(
                                    bet_amount
                            ) >= model.merge_threshold and merge_id == -1:
                                can_merge = True
                            # raise_logger("pri return", "game_bet_in", "info")
                            return {
                                'numbers': numbers,
                                'can_merge': can_merge,
                                'part_in_id': participate_in_model._id
                            }

                        else:
                            session.rollback()
                            return self.return_error(60009)
                    else:
                        session.rollback()
                        return self.return_error(60010)

                except Exception as e:
                    raise_logger(e, "game_bet_in", "info")
                    session.rollback()
                    return self.return_error(60011)

                if isinstance(numbers, int):
                    session.rollback()
                    return self.return_error(60012)

            else:
                session.rollback()
                return self.return_error(60007)
예제 #20
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
예제 #21
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)
예제 #22
0
class AccountChangeRecordModel(BaseModel):
    __tablename__ = "account_change_record"

    change_type_1 = '1'  # 充值
    change_type_2 = '2'  # 提现暂时冻结资产
    change_type_3 = '3'  # 夺宝
    change_type_4 = '4'  # 线上提现成功
    change_type_5 = '5'  # 夺宝后赢币
    change_type_6 = '6'  # 提现失败系统反还
    change_type_7 = '7'  # 线下提现成功
    change_type_13 = '13'  # 取消下注

    change_type_20 = '20'  # 新用户首次抽奖
    change_type_21 = '21'  # 新用户首次充值
    change_type_22 = '22'  # 邀请用户成功
    change_type_23 = '23'  # 受邀用户充值成功

    change_type_31 = '31'  # 扣款
    change_type_32 = '32'  # 返还
    change_type_33 = '33'  # 中奖

    # 即时开类型
    change_type_41 = '41'  # 即时开中奖
    change_type_42 = '42'  # 即时开没中奖

    # 第三方充值
    change_type_51 = '51'  # USDT 充值

    change_type_withdraw_all = '999'  # 提现的占位字段,表示包含提现中、提现完成、提现失败三个字段,不可存入数据库中
    change_type_withdraw_success = '998'  # 所有提现完成的状态,不可存入数据库中
    change_type_gold_experience = '997'  # 所有体验金的状态

    account_change_record_id = Column(String(32),
                                      unique=True,
                                      nullable=False,
                                      server_default="",
                                      comment="记录id")
    account_id = Column(String(64),
                        nullable=False,
                        server_default="",
                        comment="账户号")
    account_token_id = Column(String(64),
                              nullable=False,
                              server_default="",
                              comment="accounttoken主键")
    token_id = Column(String(255),
                      nullable=False,
                      server_default="",
                      comment="货币名称BTC、ETH、ETC、EOS……")

    change_type = Column(TINYINT(1),
                         nullable=False,
                         server_default="0",
                         comment="变化类型")
    change_amount = Column(Numeric(36, 18),
                           nullable=False,
                           default=get_decimal('0.000000000000000000'),
                           server_default=str(
                               get_decimal('0.000000000000000000')),
                           comment='币数')
    change_fee = Column(Numeric(36, 18),
                        nullable=False,
                        default=get_decimal('0.000000000000000000'),
                        server_default=str(
                            get_decimal('0.000000000000000000')),
                        comment='服务费')
    change_number = Column(INTEGER,
                           nullable=False,
                           server_default="1",
                           comment="变化数量")

    # 由于本表过大,所以不存着几个无用字段,具体字段的变化可以去其对应的record表中查询。对于提现,应该是冻结时生成记录,提现实施,update 该行数据
    # total_recharge = Column(Numeric(36, 18), nullable=False, default=get_decimal('0.000000000000000000'), server_default=str(get_decimal('0.000000000000000000')), comment='累计充值')
    # total_withdraw = Column(Numeric(36, 18), nullable=False, default=get_decimal('0.000000000000000000'), server_default=str(get_decimal('0.000000000000000000')), comment='累计提现')
    # total_withdraw_fee = Column(Numeric(36, 18), nullable=False, default=get_decimal('0.000000000000000000'), server_default=str(get_decimal('0.000000000000000000')), comment='累计提现手续费')
    balance = Column(Numeric(36, 18),
                     nullable=False,
                     default=get_decimal('0.000000000000000000'),
                     server_default=str(get_decimal('0.000000000000000000')),
                     comment='余额')
    frozon_amount = Column(Numeric(36, 18),
                           nullable=False,
                           default=get_decimal('0.000000000000000000'),
                           server_default=str(
                               get_decimal('0.000000000000000000')),
                           comment='冻结金额')
    investment_amount = Column(Numeric(36, 18),
                               nullable=False,
                               default=get_decimal('0.000000000000000000'),
                               server_default=str(
                                   get_decimal('0.000000000000000000')),
                               comment='已投金额')
    # 对于充值,则是打入token的地址,对于提现则是提出token的地址, 对于游戏则是期号
    token_address = Column(String(255),
                           nullable=False,
                           server_default="",
                           default="",
                           comment="收款地址")
    memo = Column(String(512),
                  nullable=False,
                  server_default="",
                  default="",
                  comment="memo")

    # 此操作的开始和结束时间
    begin_time = Column(DateTime,
                        nullable=False,
                        server_default="0000-00-00 00:00:00",
                        comment="开始时间")
    finish_time = Column(DateTime,
                         nullable=False,
                         server_default="0000-00-00 00:00:00",
                         comment="完成时间")
    # 交易单号,用于用户根据一条账户变换记录,反查交易详情
    transaction_id = Column(String(128),
                            nullable=False,
                            server_default="",
                            default="",
                            comment="到账交易号")
    source = Column(String(64),
                    nullable=False,
                    server_default="",
                    comment="资金来源")

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.account_change_record_id = generate_order_no()

    @staticmethod
    def get_all_show_change_type():
        return [
            AccountChangeRecordModel.change_type_1,
            AccountChangeRecordModel.change_type_3,
            AccountChangeRecordModel.change_type_13,
            AccountChangeRecordModel.change_type_5,
            AccountChangeRecordModel.change_type_withdraw_all,
            AccountChangeRecordModel.change_type_withdraw_success,
            AccountChangeRecordModel.change_type_gold_experience,
            AccountChangeRecordModel.change_type_31,
            AccountChangeRecordModel.change_type_32,
            AccountChangeRecordModel.change_type_33,
            AccountChangeRecordModel.change_type_41,
            AccountChangeRecordModel.change_type_42,
            AccountChangeRecordModel.change_type_51
        ]

    @staticmethod
    def get_all_withdraw_change_type():
        return [
            AccountChangeRecordModel.change_type_2,
            AccountChangeRecordModel.change_type_4,
            AccountChangeRecordModel.change_type_6,
            AccountChangeRecordModel.change_type_7,
        ]

    @staticmethod
    def get_all_withdraw_success_type():
        return [
            AccountChangeRecordModel.change_type_4,
            AccountChangeRecordModel.change_type_7,
        ]

    @staticmethod
    def get_all_gold_experience_type():
        return [
            AccountChangeRecordModel.change_type_20,
            AccountChangeRecordModel.change_type_21,
            AccountChangeRecordModel.change_type_22,
            AccountChangeRecordModel.change_type_23,
        ]
class ForeignWithdrawOrderRecordModel(BaseModel):
    __tablename__ = "foreign_withdraw_order_record"
    order_no = Column(String(32),
                      unique=True,
                      nullable=False,
                      server_default="",
                      comment="流水记录单号")
    relate_flow_no = Column(String(32),
                            nullable=False,
                            server_default="",
                            comment="记录 提现流水单号 或者 归集流水单号")
    req_no = Column(String(32),
                    nullable=False,
                    server_default="",
                    comment="用户请求单号")
    account_id = Column(String(64),
                        nullable=False,
                        server_default="",
                        comment="账户id")
    coin_id = Column(String(128),
                     nullable=False,
                     server_default="",
                     comment="货币id")
    from_address = Column(String(255), server_default="",
                          comment="出款地址")  # 提现:出款地址/归集地址,归集:出款地址/子账户地址
    withdraw_address = Column(String(255), server_default="",
                              comment="提现地址")  # 提现:收款地址/提现地址,归集:收款地址/归集地址
    withdraw_amount = Column(Numeric(36, 18),
                             default=get_decimal('0', 18),
                             nullable=False,
                             server_default="0.000000000000000000",
                             comment="预计提现 金额(含手续费)")
    withdraw_fee = Column(Numeric(36, 18),
                          default=get_decimal('0', 18),
                          nullable=False,
                          server_default="0.000000000000000000",
                          comment="预计提现 手续费")
    withdraw_actual_amount = Column(Numeric(36, 18),
                                    default=get_decimal('0', 18),
                                    nullable=False,
                                    server_default="0.000000000000000000",
                                    comment="提现实际到账 金额")
    withdraw_actual_fee = Column(Numeric(36, 18),
                                 default=get_decimal('0', 18),
                                 nullable=False,
                                 server_default="0.000000000000000000",
                                 comment="提现实际到账 手续费")
    withdraw_consume_total_fee = Column(Numeric(36, 18),
                                        default=get_decimal('0', 18),
                                        nullable=False,
                                        server_default="0.000000000000000000",
                                        comment="提现消耗的 手续费累计,但是交易未上块")
    amount_change = Column(Numeric(36, 18),
                           default=get_decimal('0', 18),
                           nullable=False,
                           server_default="0.000000000000000000",
                           comment="找零金额 eth交易剩余手续费")
    withdraw_gas_price = Column(Numeric(36, 18),
                                default=get_decimal('0', 18),
                                nullable=False,
                                server_default="0.000000000000000000",
                                comment="提现手续费单价")
    withdraw_type = Column(String(8),
                           nullable=False,
                           server_default="",
                           comment="提现类型: 0-用户提现, 1-用户中奖, 2-归集, 3-归集转归集")
    withdraw_status = Column(
        String(8),
        nullable=False,
        server_default="0",
        comment="提现状态: 0-未交易, 1-提现中, 2-提现成功, 3-提现失败, 4-交易失败,5-提现拒绝(审核拒绝)")
    audit_status = Column(String(8),
                          nullable=False,
                          server_default="0",
                          comment="审核状态: 0-待审核, 1-审核通过, 2-审核拒绝")
    source_status = Column(String(8),
                           nullable=False,
                           server_default="0",
                           comment="来源: 0-线上, 1-线下")
    do_withdraw_result = Column(String(255),
                                nullable=False,
                                server_default="",
                                comment="回调 账户模块 do_withdraw 结果记录")
    expect_at = Column(DateTime,
                       nullable=False,
                       server_default="0000-00-00 00:00:00",
                       comment="期望到账时间")
    process_record = Column(TEXT, comment="操作报错 业务不合法 交易处理报错等等 记录")
    transfer_at = Column(DateTime,
                         nullable=False,
                         server_default="0000-00-00 00:00:00",
                         comment="转账操作时间")
    audit_at = Column(DateTime,
                      nullable=False,
                      server_default="0000-00-00 00:00:00",
                      comment="审核通过时间")
    remark = Column(TEXT, comment="提现审核拒绝原因")
    audit_user = Column(String(255),
                        nullable=False,
                        server_default="",
                        comment="审核人")
    operation_user = Column(String(255),
                            nullable=False,
                            server_default="",
                            comment="操作人(特指线下转账录入tx的操作)")
    confirm_at = Column(DateTime,
                        nullable=False,
                        server_default="0000-00-00 00:00:00",
                        comment="到账时间")
    memo = Column(String(512), nullable=False, server_default="", comment="备注")

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
예제 #24
0
    def robot_bet_in(self, dic):
        id = dic.get("game_instance_id", "")  # 项目id
        user_id = dic.get("user_id", "")  # 用户id
        conin_id = dic.get("conin_id", 0)  # 投入币种id
        bet_amount = dic.get("bet_amount", 0)  # 投注数量
        time_stamp = dic.get("time_stamp", 0)  # 纪录时间戳

        with MysqlTools().session_scope() as session:
            # 查询项目
            model = session.query(GameDigitalInstanceModel).filter(
                GameDigitalInstanceModel._id == id).with_for_update().first()
            if model is None:
                raise_logger("机器人下注失败60001", "game_bet_in", "info")
                return 60001
            if model.status == 1:
                raise_logger("机器人下注失败60002", "game_bet_in", "info")
                return 60002
            if model.status == 2:
                raise_logger("机器人下注失败60003", "game_bet_in", "info")
                return 60003
            if model.status == 0:
                can_bet = model.need - model.bet_number
                if can_bet <= 0:
                    raise_logger("机器人下注失败60002", "game_bet_in", "info")
                    return 60005
                if int(bet_amount) > can_bet:
                    raise_logger("机器人下注失败60004", "game_bet_in", "info")
                    return 60004

            # 查询币价 币种实际需要金额
            exchange_rate = get_exchange_rate(int(conin_id))
            # (投注数量 * 投注单位) / 投注币种兑换usdt比例
            bet_money = (int(bet_amount) *
                         model.bet_unit) / exchange_rate['price']

            game_numbers = session.query(GameNumbersSetModel).filter(
                GameNumbersSetModel.game_serial ==
                model.game_serial).with_for_update().all()
            numbers = []
            for num in game_numbers:
                numbers.append(num.number)

            try:
                numbers = random.sample(numbers, int(bet_amount))
            except Exception as e:
                raise_logger("机器人下注失败 没有numbers", "game_bet_in", "info")
                return False
            if isinstance(numbers, list) and len(numbers) > 0:
                # try:
                # 修改机器人账户状态
                user = session.query(RobotAccountModel).filter(
                    RobotAccountModel.user_id ==
                    user_id).with_for_update().first()
                if user is None:
                    raise_logger("机器人下注失败70002", "game_bet_in", "info")
                    return 70002
                user.status = 0

                # 添加投注纪录
                participate_in_model = ParticipateInModel(
                    game_instance_id=model._id,
                    template_id=model.template_id,
                    game_serial=model.game_serial,
                    game_title=model.game_title,
                    release_type=model.release_type,
                    bet_unit=model.bet_unit,
                    bet_token=model.bet_token,
                    user_id=user_id,
                    nick_name=user.nick_name,
                    channel="0",
                    bet_number=int(bet_amount),
                    pay_token=int(conin_id),
                    pay_number=get_decimal(bet_money),
                    award_numbers=json.dumps(numbers),
                    user_type=1)
                session.add(participate_in_model)

                # 修改项目信息
                game_service = GameService()
                if game_service.modifyDigitalInstance(
                        model, {
                            "game_id": id,
                            "add_bet_number": int(bet_amount),
                            "full_load_time": participate_in_model.created_at,
                            "add_people": 1
                        }) is False:
                    session.rollback()
                    raise_logger("机器人下注失败80005", "game_bet_in", "info")
                    return 80005

                # 修改机器人配置纪录 下注状态
                record = session.query(RobotConfigRecordModel).filter(
                    RobotConfigRecordModel.game_instance_id == id,
                    RobotConfigRecordModel.user_id == user_id,
                    RobotConfigRecordModel.time_stamp ==
                    time_stamp).with_for_update().first()
                if record is None:
                    raise_logger("机器人下注失败70002", "game_bet_in", "info")
                    return 70002
                record.bet_status = 1

                # 查看本期 机器人是否都已下注完成
                is_finish = True
                robots = session.query(RobotConfigRecordModel).filter(
                    RobotConfigRecordModel.game_instance_id == id,
                    RobotConfigRecordModel.time_stamp == time_stamp).all()
                for r in robots:
                    if r.bet_status == 0 or r.bet_status == 2:
                        is_finish = False
                        break

                if is_finish:
                    # 修改 游戏机器人配置纪录
                    q = session.query(RobotGameConfigRecordModel).filter(
                        RobotGameConfigRecordModel.game_instance_id == id,
                        RobotGameConfigRecordModel.time_stamp ==
                        time_stamp).with_for_update().first()

                    if q is None:
                        raise_logger("机器人下注失败70003", "game_bet_in", "info")
                        return 70003

                    q.status = 2
                    q.end_of_real_time = datetime.datetime.utcnow().strftime(
                        '%Y-%m-%d %H:%M:%S')

                session.flush()

                try:
                    created_at_str = str(participate_in_model.created_at)
                    update_at_str = str(participate_in_model.update_at)
                    deleted_at_str = str(participate_in_model.deleted_at)
                    deleted_str = str(participate_in_model.deleted)
                    dic = {
                        "id": participate_in_model._id,
                        "created_at": created_at_str[0:19],
                        "update_at": update_at_str[0:19],
                        "deleted_at": deleted_at_str[0:19],
                        "deleted": deleted_str[0:19],
                        "game_instance_id":
                        participate_in_model.game_instance_id,
                        "template_id": participate_in_model.template_id,
                        "game_serial": participate_in_model.game_serial,
                        "bet_token": participate_in_model.bet_token,
                        "user_id": participate_in_model.user_id,
                        "nick_name": participate_in_model.nick_name,
                        "channel": participate_in_model.channel,
                        "pay_token": participate_in_model.pay_token,
                        "bet_number": participate_in_model.bet_number,
                        "pay_number": str(participate_in_model.pay_number),
                        "award_numbers": participate_in_model.award_numbers,
                        "user_type": participate_in_model.user_type,
                    }

                    if BlockChainInfoService().insert_block_chain_info(
                            user_id, participate_in_model.game_instance_id, 1,
                            dic):
                        participate_in_model.chain_status = 1

                except Exception as e:
                    session.rollback()
                    raise_logger("insert_block_chain_info", "game_bet_in",
                                 "info")

                g_service = model.game_serial
                for i in numbers:
                    session.query(GameNumbersSetModel).filter(
                        GameNumbersSetModel.game_serial == g_service,
                        GameNumbersSetModel.number == i).delete()
                # # 检测游戏是否售罄需要申请开奖
                if int(model.status) == 1:
                    add_result = WalletEosService().lottery_adduce(
                        id, get_timestamp(model.full_load_time))
                    if not add_result:
                        raise_logger("lottery_adduce fail", "game_bet_in",
                                     "info")

                session.commit()

                try:
                    # # 提交验证是否需要上线新项目
                    game_service.automatic_release(session, model.template_id)
                except Exception as e:
                    raise_logger("automatic_release", "game_bet_in", "info")

                return True

            # except Exception as e:
            #     session.rollback()
            #     raise_logger("机器人下注失败60006", "game_bet_in", "info")
            #     return 60006

            return False