Example #1
0
    def gather_to_gather(self, coin_id, from_address, amount, to_address, verification_code):
        """
        归集转归集
        :param coin_id: 币种
        :param from_address: 待归集地址
        :param amount: 归集数量
        :param to_address: 收款地址
        :param verification_code: 验证码
        :return:
        """
        conf = get_config()
        env = conf["env"]
        if env == "pd":
            vcode_service = VcodeService()
            result = vcode_service.check_sms_email_vcode('common', verification_code)
        with MysqlTools().session_scope() as session:
            record_id = generate_order_no()
            foreign_gather_record = ForeignGatherRecordModel(
                record_id=record_id,
                public_address=to_address,
                purpose_amount=amount,
                gather_status=_FOUR_S
            )
            session.add(foreign_gather_record)
            gather_record_id = foreign_gather_record.record_id
            order_no = generate_order_no()
            withdraw = ForeignWithdrawOrderRecordModel(
                order_no=order_no,
                relate_flow_no=gather_record_id,
                coin_id=coin_id,
                from_address=from_address,
                withdraw_address=to_address,
                withdraw_amount=amount,
                withdraw_type=_THREE_S,
                withdraw_status=_ZERO_S,
                audit_status=_ONE_S,
                source_status=_ZERO_S,
                transfer_at=get_utc_now()
            )
            session.add(withdraw)
            session.commit()
            withdraw_order_no = withdraw.order_no
            withdraw = session.query(ForeignWithdrawOrderRecordModel).filter(
                ForeignWithdrawOrderRecordModel.order_no == order_no).first()
            wfs = WalletForeignService()
            send_result = None
            if coin_id == _ZERO_S:  # 比特币
                send_result = wfs.btc_send_tx(withdraw)
            elif coin_id == _SIXTY_S:  # 以太坊
                send_result = wfs.eth_send_tx(withdraw)

            if send_result is True:
                gather_record_model = session.query(ForeignGatherRecordModel).filter(ForeignGatherRecordModel.record_id == gather_record_id).first()
                gather_record_model.gather_status = _ONE_S
                withdraw_reocrd_model = session.query(ForeignWithdrawOrderRecordModel).filter(ForeignWithdrawOrderRecordModel.order_no == withdraw_order_no).first()
                withdraw_reocrd_model.withdraw_status = _ONE_S
                session.commit()
            return
Example #2
0
 def check_instance_exp_limit(self, session, user_id, game_instance_id):
     exp_coin_id = int(_COIN_ID_EXP)
     result = {'instance_limit': 0, 'user_limit': 0}
     # with MysqlTools().session_scope() as session:
     instance_exp_limit = session.query(func.sum(ParticipateInModel.bet_number * ParticipateInModel.bet_unit)). \
         filter(ParticipateInModel.game_instance_id == game_instance_id,
                ParticipateInModel.pay_token == exp_coin_id).first()
     user_limit = session.query(func.sum(ParticipateInModel.bet_number * ParticipateInModel.bet_unit)). \
         filter(ParticipateInModel.user_id == user_id,
                ParticipateInModel.game_instance_id != 0,
                ParticipateInModel.pay_token == exp_coin_id,
                func.date_format(ParticipateInModel.created_at, "%Y-%m-%d") ==
                func.date_format(get_utc_now(), "%Y-%m-%d")).first()
     if instance_exp_limit[0] is not None:
         result['instance_limit'] = int(instance_exp_limit[0])
     if user_limit[0] is not None:
         result['user_limit'] = int(user_limit[0])
     return result
 def automatic_release(self, session, template_id):
     # now = int(time.time())
     # time_struct = time.localtime(now)
     # str_time = time.strftime("%Y-%m-%d %H:%M:%S", time_struct)
     template_id = 1
     str_time = get_utc_now()
     with MysqlTools().session_scope() as session:
         template_info = session.query(InstantGameTemplateModel). \
             filter(InstantGameTemplateModel._id == template_id).first()
         # 判断存在在"启用"状态 且 自动发布的模板
         if template_info.template_status == 1 and template_info.auto_release == 1:
             # 查询btc 与 usdt 转换比
             btc_usdt_rate = get_exchange_rate(
                 template_info.reward_token)['price']
             if btc_usdt_rate > template_info.need_ceiling or btc_usdt_rate < template_info.need_floor:
                 raise_logger("automatic_release out of rate", 'rs',
                              'error')
                 return {"status": False}
             need = btc_usdt_rate * template_info.reward_quantity
             game_serial = generate_phase(str(template_info.phase_prefix))
             digital_instance_model = InstantGameInstanceModel(
                 template_id=template_id,
                 game_serial=game_serial,
                 game_title=template_info.game_title,
                 bet_token=template_info.bet_token,
                 bet_unit=template_info.bet_unit,
                 support_token=template_info.support_token,
                 reward_token=template_info.reward_token,
                 reward_quantity=template_info.reward_quantity,
                 handling_fee=template_info.handling_fee,
                 game_describe=template_info.game_describe,
                 experience=template_info.experience,
                 merge_threshold=template_info.merge_threshold,
                 max_bet_ratio=template_info.max_bet_ratio,
                 release_time=str_time,
                 need=int(need),
                 status=-1,
                 release_type=1,
                 chain_status=0)
             session.add(digital_instance_model)
             # session.flush()
             session.commit()
         return {"status": True}
 def manual_release(self, template_id, game_serial, need, game_describe):
     if not need.isdigit():
         self.return_error(40008)
     # now = int(time.time())
     # time_struct = time.localtime(now)
     # str_time = time.strftime("%Y-%m-%d %H:%M:%S", time_struct)
     str_time = get_utc_now()
     with MysqlTools().session_scope() as session:
         template_info = session.query(InstantGameTemplateModel). \
             filter(InstantGameTemplateModel._id == template_id).first()
         if template_info is None:
             self.return_error(50001)
         if int(template_info.need_ceiling) < int(template_info.need_floor):
             self.return_error(40009)
         need = int(need) * template_info.reward_quantity
         digital_instance_model = InstantGameInstanceModel(
             template_id=template_id,
             game_serial=game_serial,
             game_title=template_info.game_title,
             bet_token=template_info.bet_token,
             bet_unit=template_info.bet_unit,
             support_token=template_info.support_token,
             reward_token=template_info.reward_token,
             reward_quantity=template_info.reward_quantity,
             handling_fee=template_info.handling_fee,
             experience=template_info.experience,
             merge_threshold=template_info.merge_threshold,
             game_describe=game_describe,
             release_time=str_time,
             status=0,
             need=int(need),
             release_type=0,
             chain_status=0)
         session.add(digital_instance_model)
         # session.flush()
         session.commit()
     return {"status": True}
Example #5
0
    def check_game_sold_out_by_eos(self, id, block_no, block_hash, timestamp,
                                   received_time):
        with MysqlTools().session_scope() as session:
            model = session.query(GameDigitalInstanceModel).filter(
                GameDigitalInstanceModel._id == id,
                GameDigitalInstanceModel.status ==
                1).with_for_update().first()
            if model is None:
                return False
            result_block = {
                'block_no': block_no,
                'block_hash': block_hash,
                'timestamp': timestamp,
                'received_time': received_time
            }
            hash_numbers = result_block["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
            raise_logger("项目:" + str(id) + "    中奖号码:" + str(prize_number),
                         "game_publish_lottery", "info")
            # print("中奖号码", str(prize_number))

            participate_in = ParticipateInService()
            records = participate_in.search_model(session, id)
            # 无人参与
            if len(records) <= 0:
                raise_logger("无人参与80002", "game_publish_lottery", "info")
                return False

            user_id = ""
            user_pay_token = 0
            user_bet_number = 0
            user_type = 0
            merge_id = -1
            part_in_id = -1
            for item in records:
                numbers = json.loads(item.award_numbers)
                if prize_number in numbers:
                    part_in_id = item._id
                    user_id = item.user_id
                    user_pay_token = item.pay_token
                    user_bet_number = item.bet_number
                    user_type = item.user_type
                    merge_id = item.merge_id
                    break

            # 无人中奖
            if user_id == "":
                raise_logger("无人中奖80003", "game_publish_lottery", "info")
                return False

            raise_logger("中奖user_id:" + str(user_id), "game_publish_lottery",
                         "info")

            win_record = session.query(GameDigitalInstanceModel).filter(
                WinningRecordModel.game_instance_id == id).first()
            # game_instance_id已经存在开奖纪录
            if win_record:
                raise_logger(str(id) + "开奖纪录", "game_publish_lottery", "info")
                return False

            # 修改game实体添加开奖时间 和币价信息
            game_service = GameService()
            lottery_time_str = str(get_utc_now())
            lottery_time = lottery_time_str[0:19]

            if game_service.modifyDigitalInstance(model, {
                    "game_id": id,
                    "lottery_time": lottery_time
            }) is False:
                raise_logger("开奖纪录modifyDigitalInstance   False",
                             "game_publish_lottery", "info")
                return False

            raise_logger("开奖纪录modifyDigitalInstance 修改成功",
                         "game_publish_lottery", "info")

            try:
                # 添加开奖纪录
                winning_record_model = WinningRecordModel(
                    created_at=lottery_time,
                    game_instance_id=id,
                    game_serial=model.game_serial,
                    bet_serial=str(prize_number),
                    bet_hash=hash_numbers,
                    reward_token=model.reward_token,
                    reward_quantity=model.reward_quantity,
                    user_id=user_id,
                    bet_token=user_pay_token,
                    bet_number=user_bet_number,
                    user_type=user_type,
                    block_no=result_block['block_no'],
                    timestamp=result_block['timestamp'],
                    received_time=result_block['received_time'],
                    participation=model.participation,
                    block_type="0",
                    merge_id=merge_id)
                session.add(winning_record_model)
                session.flush()

                raise_logger("添加开奖纪录", "game_publish_lottery", "info")

                # 真实用户 添加 中奖金额
                if user_type == 0:
                    account_service = AccountService()
                    # 合买逻辑
                    if merge_id != -1:
                        raise_logger("合买逻辑", "game_publish_lottery", "info")
                        total_bet = session.query(func.sum(ParticipateInModel.bet_number).label('total')). \
                            filter(ParticipateInModel.merge_id == merge_id).first()
                        win_users = session.query(ParticipateInModel). \
                            filter(ParticipateInModel.merge_id == merge_id).all()
                        for win_user in win_users:
                            reward_quantity = win_user.bet_number / int(float(total_bet.total)) * model.reward_quantity \
                                              * (1 - float(model.handling_fee) / 100)
                            result = account_service.do_win_new_session(
                                win_user.user_id, model.reward_token,
                                decimal.Decimal(reward_quantity),
                                str(part_in_id), win_user.bet_number,
                                win_user.game_serial)
                            if isinstance(result, int) is False:
                                raise_logger(
                                    "分钱失败" + "user:"******"game_publish_lottery", "info")
                                session.rollback()
                                return False
                            if result != 0:
                                raise_logger(
                                    "分钱失败" + "user:"******"game_publish_lottery", "info")
                                session.rollback()
                                return False
                    else:
                        raise_logger("非合买逻辑", "game_publish_lottery", "info")
                        # 实际奖励金额 = 奖励金额 * (1-手续费%)
                        reward_quantity = model.reward_quantity * (
                            1 - model.handling_fee / 100)
                        result = account_service.do_win(
                            session, user_id, model.reward_token,
                            reward_quantity, str(part_in_id), user_bet_number,
                            model.game_serial)

                        if isinstance(result, int) is False:
                            raise_logger("分钱失败" + "user:"******"game_publish_lottery", "info")
                            session.rollback()
                            return False
                        if result != 0:
                            raise_logger("分钱失败" + "user:"******"game_publish_lottery", "info")
                            session.rollback()
                            return False

                raise_logger("分钱成功", "game_publish_lottery", "info")

                try:
                    # 添加上链数据
                    lottery_time_str = str(model.lottery_time)
                    release_time_str = str(model.release_time)
                    full_load_time_str = str(model.full_load_time)
                    nick_name = session.query(
                        ParticipateInModel.nick_name).filter(
                            ParticipateInModel.user_id == user_id).first()
                    if BlockChainInfoService().insert_block_chain_info(
                            "", id, 0,
                        {
                            "id": winning_record_model._id,
                            "game_instance_id":
                            winning_record_model.game_instance_id,
                            "game_serial": winning_record_model.game_serial,
                            "bet_serial": winning_record_model.bet_serial,
                            "bet_hash": winning_record_model.bet_hash,
                            "reward_token": winning_record_model.reward_token,
                            "reward_quantity":
                            winning_record_model.reward_quantity,
                            "user_id": winning_record_model.user_id,
                            "bet_token": winning_record_model.bet_token,
                            "bet_number": winning_record_model.bet_number,
                            "user_type": winning_record_model.user_type,
                            "block_no": winning_record_model.block_no,
                            "timestamp": winning_record_model.timestamp,
                            "received_time":
                            winning_record_model.received_time,
                            "block_type": winning_record_model.block_type,
                            "participation":
                            winning_record_model.participation,
                            "lottery_time": lottery_time_str[0:19],
                            "game_describe": model.game_describe,
                            "nick_name": nick_name,
                            "need": model.need,
                            "release_time": release_time_str[0:19],
                            "full_load_time": full_load_time_str[0:19],
                        }):
                        winning_record_model.chain_status = 1

                except Exception as e:
                    raise_logger("开奖insert_block_chain_info     Exception",
                                 "game_publish_lottery", "info")
                session.commit()
                return True

            except Exception as e:
                raise_logger(e.__str__(), "game_publish_lottery", "info")
                session.rollback()
                return False
Example #6
0
    def automatic_release_instance(self):
        # now = int(time.time())
        # time_struct = time.localtime(now)
        # str_time = time.strftime("%Y-%m-%d %H:%M:%S", time_struct)
        str_time = get_utc_now()

        with MysqlTools().session_scope() as session:
            template_result = session.query(GameDigitalTemplateModel). \
                filter(GameDigitalTemplateModel.template_status == 1,
                       GameDigitalTemplateModel.auto_release == 1).all()
            if len(template_result) > 0:
                for row in template_result:
                    btc_usdt_rate = get_exchange_rate(
                        row.reward_token)['price']
                    ceiling = row.need_ceiling
                    floor = row.need_floor
                    email_config = get_sms_email('common')
                    if email_config == {}:
                        self.return_error(35034)
                    send_email_config = get_sms_email("send_email_config")
                    subject = email_config['email_subject']
                    if btc_usdt_rate > ceiling or btc_usdt_rate < floor:
                        self.slog.info("instantiation fail. rate is ",
                                       str(btc_usdt_rate))
                        self.slog.info("game template id is ", str(row._id))
                        # 警告邮件
                        send_mail(
                            "game自动实例化失败, GAME模板id:" + str(row._id) +
                            ",奖励币种价格:" + str(btc_usdt_rate),
                            send_email_config['user'],
                            send_email_config['pwd'], email_config['email'],
                            subject, send_email_config['smtp_server'],
                            send_email_config['smtp_port'])
                    else:
                        template_id = row._id
                        instance_list = session.query(GameDigitalInstanceModel). \
                            filter(GameDigitalInstanceModel.status == 0,
                                   GameDigitalInstanceModel.template_id == template_id).all()
                        if len(instance_list) <= 0:
                            phase_prefix = row.phase_prefix
                            need = btc_usdt_rate * row.reward_quantity * (
                                (100 + row.exceeded_ratio) / 100)
                            game_serial = generate_phase(str(phase_prefix))
                            digital_instance_model = GameDigitalInstanceModel(
                                template_id=template_id,
                                game_serial=game_serial,
                                game_title=row.game_title,
                                bet_token=row.bet_token,
                                bet_unit=row.bet_unit,
                                support_token=row.support_token,
                                reward_token=row.reward_token,
                                reward_quantity=row.reward_quantity,
                                handling_fee=row.handling_fee,
                                game_describe=row.game_describe,
                                experience=row.experience,
                                merge_threshold=row.merge_threshold,
                                release_time=str_time,
                                need=int(need),
                                status=0,
                                release_type=1,
                                chain_status=0)
                            # if create_all_bet_number(game_serial, int(need)) != 2000:
                            #     self.slog.info("create all bet number fail")
                            if not GameNumberSetService().createNumbers(
                                {
                                    "game_serial": game_serial,
                                    "total": int(need)
                                }):
                                self.slog.info("create all bet number fail")
                                self.return_error(40015)
                            session.add(digital_instance_model)
                            session.flush()
                            try:
                                # 发布信息上链
                                if BlockChainInfoService(
                                ).insert_block_chain_info(
                                        '', str(digital_instance_model._id), 2,
                                    {
                                        "instance_id":
                                        digital_instance_model._id,
                                        "template_id":
                                        template_id,
                                        "game_serial":
                                        game_serial,
                                        "support_token":
                                        row.support_token,
                                        "bet_token":
                                        row.bet_token,
                                        "bet_unit":
                                        row.bet_unit,
                                        "reward_token":
                                        row.reward_token,
                                        "reward_quantity":
                                        row.reward_quantity,
                                        "handling_fee":
                                        str(row.handling_fee),
                                        "game_describe":
                                        row.game_describe,
                                        "release_time":
                                        str_time.strftime("%Y-%m-%d %H:%M:%S"),
                                        "status":
                                        0,
                                        "need":
                                        int(need),
                                        "release_type":
                                        0,
                                    }):
                                    digital_instance_model.chain_status = 1
                                    self.slog.info(
                                        "insert_block_chain_info success")
                                else:
                                    self.slog.info(
                                        "insert_block_chain_info fail")
                            except Exception as e:
                                self.slog.info("insert_block_chain_info fail")
                                self.slog.info(f"Exception: {e}")
                                # self.slog.info("automatic_release_instance fail")
                                # session.rollback()
                            session.commit()
                            # send_mail("game自动实例化成功, GAME模板id:" + str(template_id) + ",奖励币种价格:" + str(btc_usdt_rate),
                            #           send_email_config['user'], send_email_config['pwd'],
                            #           email_config['email'],
                            #           subject, send_email_config['smtp_server'], send_email_config['smtp_port'])
                            self.slog.info(
                                "automatic_release_instance success")
    def 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)
        }
Example #8
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