def tx_process(session, tx_id, operator: ERC20Token): """交易处理函数""" tx_data = operator.get_transaction_data(tx_id) from_address = tx_data.from_address black_list = get_black_list() if from_address in black_list: return if not check_account_exists(session, tx_data.to_address): return coin = coin_type if tx_data.token_address: coin_info = session.query(coin_setting_document).filter_by( coin_setting_document.token_address.in_( (tx_data.token_address, to_normalized_address(tx_data.token_address)))).first() if not coin_info: logger.error(f'not found token address: {tx_data.token_address}') return coin = coin_info.coin_type tx_data.token_amount = from_unit(tx_data.token_amount, coin_info.token_unit) recharge_record = session.query(coin_recharge_document).filter_by( txid=tx_id).first() if recharge_record: return data = { 'amount': tx_data.ether_amount, 'txid': tx_id, 'created_at': datetime.utcnow(), 'confirmation_count': tx_data.num_confirmations, 'from_address': tx_data.from_address, 'to_address': tx_data.to_address, 'coin_type': coin, 'coin_series': coin_type, } r = Recharge(**data) session.add(r) try: session.commit() except Exception as e: logger.exception("冲币记录到数据库时发生错误{}".format(e)) session.rollback() raise else: recharge(address=data["to_address"], from_address=data["from_address"], amount=float(data["amount"]), txid=data["txid"], coin_type=data["coin_type"], confirmations=data["confirmation_count"], status=0, destination_tag=None) logger.info('检测到{}充币到{}{}个'.format(tx_data.from_address, tx_data.to_address, tx_data.ether_amount))
def tx_process(self, session, tx_id, operator): """交易处理函数""" tx_data = operator.get_transaction_data(tx_id) now = dt.datetime.utcnow() user_info = session.query(self.coin_address_coll).filter_by( pub_address=tx_data.to_address).first() if not user_info: return # 是否为用户线下交易(从平台内一个账户提 ll币到另外一个账户) is_not_offline = 0 < float(tx_data.ether_amount) <= float( config.etc_fee_min) if self.is_in_black_list(tx_data, is_not_offline): return recharge_record = session.query( self.coin_recharge_coll).filter_by(txid=tx_id).first() if recharge_record: return data = dict() data['amount'] = float(tx_data.ether_amount) data['txid'] = tx_id data['created_at'] = now, data['status'] = RechargeStatusEnum.RECHARGE data['done_at'] = '' data['confirmation_count'] = tx_data.num_confirmations data['updated_at'] = now data['from_address'] = tx_data.from_address data['to_address'] = tx_data.to_address data['destination_tag'] = '' data['coin_type'] = self.coin_category data['coin_series'] = self.coin_category, data['comment'] = '', data['informed'] = InformEnum.NO logger.info((f"""{data["coin_type"]} {data["amount"]} {data["confirmation_count"]}""")) recharge_record = self.coin_recharge_coll(**data) try: session.add(recharge_record) session.commit() except Exception as e: logger.exception("插入冲币记录发生错误{}".format(e)) session.rollback() raise else: recharge(address=data['to_address'], from_address=data['from_address'], amount=data['amount'], txid=data['txid'], coin_type=data['coin_type'], confirmations=data['confirmation_count'], status=0)
def send_recharge_notify(recharge_record): try: recharge_record_ = vars(recharge_record) \ if recharge_record else dict() recharge_address = recharge_record_.get('to_address', '') recharge_amount = recharge_record_.get('amount', 0) transaction_id = recharge_record_.get('txid', '') coin_type = recharge_record_.get('coin_type', '') from_address = recharge_record_.get('from_address', '') confirmations = recharge_record_.get('confirmation_count', 0) recharge_status = recharge_record_.get('status', RechargeStatusEnum.RECHARGE) response = recharge(address=recharge_address, from_address=from_address, amount=float(recharge_amount), txid=transaction_id, coin_type=coin_type, confirmations=confirmations, status=recharge_status.value) if transaction_id and response.get("result", "") == transaction_id: logger.info('已成功通知充币交易{}'.format(response)) if recharge_status.value in [SUCCESS, FAIL]: recharge_record.informed = InformEnum.YES else: logger.error('java后台没有确认{}冲币通知{}'.format( coin_type, transaction_id)) except Exception as e: logger.exception('java接口调用失败{}'.format(e))
def send_recharge_notify(session, recharge_record): try: recharge_record_ = vars(recharge_record) \ if recharge_record else dict() recharge_address = recharge_record_.get('to_address', '') recharge_amount = recharge_record_.get('amount', 0) transaction_id = recharge_record_.get('txid', '') coin_type = recharge_record_.get('coin_type', '') from_address = recharge_record_.get('from_address', '') confirmations = recharge_record_.get("confirmation_count", 0) status = recharge_record_.get("status", RechargeStatusEnum.RECHARGE) response = recharge(address=recharge_address, from_address=from_address, amount=recharge_amount, txid=transaction_id, coin_type=coin_type, confirmations=confirmations, status=status.value) if transaction_id and response == transaction_id: if status.value in [SUCCESS, FAIL]: try: recharge_record.informed = InformEnum.YES session.commit() except Exception as e: logger.exception("修改充币通知状态失败{}".format(e)) session.rollback() else: logger.info('已成功修改充币状态') logger.info('已成功通知充币交易{}'.format(response)) else: logger.error('java后台没有确认{}提币通知{}'.format( coin_type, transaction_id)) except Exception as e: logger.exception(e)
def check_recharge(): u = USDTOP(config.usdt_rpc_uri, config.timeout) for each in u.list_transactions(): record = {} if each.get('abandoned', False): logger.warning('recharge abandoned: {}'.format(each)) continue if not each.get('valid', True): logger.warning('recharge invalid: {}'.format(each)) continue if each.get('propertyid') != property_id: continue if each.get('category') == 'send': continue to_address = each.get('referenceaddress') rv = Account.find_one({ 'coin_type': coin_type, 'pub_address': to_address }) if not rv or not rv.get('is_used'): continue tx_id = each['txid'] confirmation_count = each['confirmation_count'] rv = Recharge.find_one({'coin_type': coin_type, 'txid': tx_id}) if rv: cr = CheckRecharge(rv, config.usdt_confirmation) cr.update_confirmations(confirmation_count) else: record['to_address'] = to_address record['amount'] = each['amount'] record['txid'] = each['txid'] record['fee'] = each['fee'] record['from_address'] = each['sendingaddress'] record['coin_type'] = coin_type record['coin_series'] = 'BTC' if confirmation_count > config.usdt_confirmation: record['status'] = RechargeStatusEnum.SUCCESS record['done_at'] = datetime.utcnow() record['confirmation_count'] = confirmation_count try: rv = rpc_call.recharge(to_address, record['from_address'], record['amount'], record['txid'], coin_type, confirmation_count, record['status']) if rv == record['txid']: record['informed'] = InformEnum.YES except Exception as e1: logger.exception(e1) Recharge(**record).insert()
def notify(self, tx_id, confirmations, status=0): """ 发送通知到java服务器 :param tx_id: 交易哈希 :param confirmations: 确认数 :param status: 状态,如果确认数还不够,此参数不传,如果确认数足够则发送TbStatusEnum.SUCCESS :return: """ coin_type = self.item['coin_type'] if self.type == 'withdraw': return rpc_call.confirm(tx_id, confirmations, status, coin_type) else: to_address = self.item['to_address'] from_address = self.item['from_address'] amount = self.item['amount'] destination_tag = self.item['destination_tag'] return rpc_call.recharge(to_address, from_address, amount, tx_id, coin_type, confirmations, status, destination_tag)
def update_informed(cls, coin_type, _type): assert _type in cls.__type__ if _type == 'withdraw': success_status = TbStatusEnum.SUCCESS inform_list = TbRecord.find({ 'status': success_status, 'coin_type': coin_type, 'informed': InformEnum.NO }) else: success_status = RechargeStatusEnum.SUCCESS inform_list = Recharge.find({ 'status': success_status, 'coin_type': coin_type, 'informed': InformEnum.NO }) for each in inform_list: tx_id = each['txid'] try: if _type == 'withdraw': rv = rpc_call.confirm(tx_id, each['confirmation_count'], success_status, coin_type) elif _type == 'recharge': to_address = each['to_address'] from_address = each['from_address'] amount = each['amount'] destination_tag = each['destination_tag'] confirmations = each['confirmation_count'] rv = rpc_call.recharge(to_address, from_address, amount, tx_id, coin_type, confirmations, success_status, destination_tag) if rv == tx_id: each['informed'] = InformEnum.YES except Exception as e: logger.error(f'调用confirm接口失败.{self.item}') logger.exception(e) try: TbRecord.replace_one({'id': each['id']}, each) except Exception as e: logger.error(f'写入数据库失败{each}') logger.exception(e)
def send_recharge_notify(self, session, recharge_record_): try: recharge_record = vars(recharge_record_) \ if recharge_record_ else dict() recharge_address = recharge_record.get('to_address', '') recharge_amount = recharge_record.get('amount', 0) transaction_id = recharge_record.get('txid', '') from_address = recharge_record.get('from_address', '') confirmations = recharge_record.get("confirmation_count", 0) status = recharge_record.get("status", RechargeStatusEnum.RECHARGE) response = recharge(address=recharge_address, from_address=from_address, amount=recharge_amount, txid=transaction_id, coin_type=self.coin_category, confirmations=confirmations, status=status.value) if transaction_id and response == transaction_id: logger.info('已成功通知充币交易{}'.format(response)) if status.value in [ RechargeStatusEnum.SUCCESS.value, RechargeStatusEnum.FAILED.value ]: try: recharge_record_.informed = InformEnum.YES session.commit() except Exception as e: logger.exception("修改充值记录是否通知字段失败{}".format(e)) session.rollback() else: logger.info('已成功修改充币交易状态') else: logger.error('java后台没有确认{}冲币通知{}'.format( self.coin_category, transaction_id)) except Exception as e: logger.exception("java借口调用失败{}".format(e))
def check_recharge(self): """ 充币检测 """ xlm = XlmOP(config, config.xlm_tb_url) # 获取oplsit logger.info('*' * 20) res_list = xlm.get_operations(config.xlm_cb_address) for each in res_list: logger.info(f'交易xinxi{each}+++++') tx_id = each['transaction_hash'] # 根据交易id获取memo tx_data = xlm.get_trans_info(tx_id) # huoqu zuixin ledger rec = xlm.get_ledgers() new_ledgers = rec[0].get('sequence', '') comfire_ledgers = new_ledgers - tx_data.get('ledger', '') if not comfire_ledgers > config.xlm_confirmation: logger.info(f'交易id: {tx_id}冲币失败') continue memo = tx_data['memo'] to_address = each.get('to') from_address = each.get('from') rv = Account.find_one({ 'coin_type': coin_type, 'pub_address': to_address, 'destination_tag': memo }) # 不是我们平台创建的地址 continue if not rv or not rv['is_used']: continue recharge_rec = Recharge.find_one({ 'coin_type': coin_type, 'txid': tx_id }) if recharge_rec: cr = CheckRecharge(rv, config.xlm_confirmation) cr.update_confirmations(comfire_ledgers) # 如果不存在则往数据库插入此交易记录 else: record = dict() record['to_address'] = to_address record['amount'] = each['amount'] record['txid'] = each['transaction_hash'] record['fee'] = tx_data['fee_paid'] record['from_address'] = from_address record['coin_type'] = coin_type if comfire_ledgers >= config.xlm_confirmation: record['status'] = RechargeStatusEnum.SUCCESS record['done_at'] = datetime.utcnow() record['confirmation_count'] = comfire_ledgers try: # 通知java组充值成功,java组确认再通知我们返回交易id rv = rpc_call.recharge(to_address, from_address, record['amount'], tx_id, coin_type, comfire_ledgers, record['status'], memo) # 防止因服务器挂掉rv返回空值增加判断 if rv == record['txid']: record['informed'] = InformEnum.YES except Exception as e1: logger.exception(e1) try: Recharge(**record).insert() except Exception as e: logger.exception(e)