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
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}
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
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) }
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