def bhd_converge(): # listunspent 获取用户地址未消费收益 addresses = db.session.query(PoolAddress.address).filter_by(coin_name=BHD_COIN_NAME).all() addresses = [address[0] for address in addresses] unspents = bhd_client.list_unspent(addresses=addresses, minimumAmount=MIN_CONVERGE_AMOUNT_BHD) if not unspents: return account_balance = {} account_address = {} # 统计地址未花费交易总额 for unspent_trx in unspents: address = unspent_trx['address'] # 老大地址,因为和primary 在一个account,特殊处理。 if address == BHD_MINER_ADDRESS: continue account = unspent_trx['account'] amount = unspent_trx['amount'] confirmations = unspent_trx['confirmations'] spendable = unspent_trx.get('spendable', False) total_amount = account_balance.get(account, 0) if not spendable: continue if confirmations < MIN_CONFIRMED[BHD_COIN_NAME]: continue account_balance[account] = total_amount + amount account_address[account] = address all_total_amount = bhd_client.get_balance() - MIN_FEE tx_id = bhd_client.withdrawal(BHD_MINER_ADDRESS, all_total_amount) for account, balance in account_balance.items(): converge_amount = balance - POUNDAGE_BALANCE address = account_address.get(account) bhd_address = PoolAddress.query.filter_by(address=address).first() if not bhd_address: continue account_key = bhd_address.account_key try: # todo 添加记录,但是最后,直接获取总额,转账到提现地址。 billing = Billings(account_key, converge_amount, address, BHD_MINER_ADDRESS, BHD_CONVERGE, tx_id) db.session.add(billing) db.session.commit() celery_logger.info("bhd_converge %s" % billing.to_dict()) except Exception as e: db.session.rollback() celery_logger.error("bhd_converge %s" % e)
def check_pledges(): """ 对比库中和链上数据,检查抵押状态的交易是否撤销,并处理。 :return: """ remote_pledges = RemotePledgeTransaction.query.filter_by( status=DEBITING).all() pledges = bhd_client.list_pledges() if not remote_pledges: return pledges_txids = [pledge["txid"] for pledge in pledges] for remote_pledge in remote_pledges: if remote_pledge.pledge_txid in pledges_txids: # 抵押状态正常 continue try: user_asset = UserAsset.query.filter_by( account_key=remote_pledge.account_key, coin_name=BHD_COIN_NAME).with_for_update(read=False).first() if not user_asset: continue celery_logger.info("user_asset before deduct %s" % user_asset.to_dict()) coop_freeze_asset = user_asset.coop_freeze_asset total_pledge_amount = user_asset.get_pledge_amount() remote_pledge_amount = remote_pledge.pledge_amount # 首先扣掉远程借贷总数 reside_no_debit_amount = user_asset.get_remote_avai_amount() user_asset.remote_freeze_asset -= remote_pledge_amount if reside_no_debit_amount >= remote_pledge_amount: remote_pledge.status = DEBIT_UNDONE db.session.commit() continue # 远程抵押中剩余可用不够扣除的。需要扣除远程合作和远程抵押中的资金 remote_deduct = remote_pledge_amount - reside_no_debit_amount # 如果可用的能覆盖,不需要改动合作冻结资金 if user_asset.available_asset >= remote_deduct: # 从可用中扣除全部 user_asset.available_asset -= remote_deduct # 从远程合作和远程抵押中扣 if user_asset.remote_4coop_asset >= remote_deduct: # 从合作中直接扣除 user_asset.remote_4coop_asset -= remote_deduct else: # 远程合作中扣除全部,抵押中扣除一部分。合作总额、抵押总额不变,可用补足 deduct_pledge_amount = remote_deduct - user_asset.remote_4coop_asset user_asset.remote_4pledge_asset -= deduct_pledge_amount user_asset.pledge_asset += deduct_pledge_amount user_asset.remote_4coop_asset = 0 # 如果可用余额不能覆盖,可用余额优先补足抵押 else: if user_asset.remote_4coop_asset >= remote_deduct: # 只扣远程合作中的余额 user_asset.remote_4coop_asset -= remote_deduct deduct_coop_freeze = remote_deduct - user_asset.available_asset user_asset.coop_freeze_asset -= deduct_coop_freeze else: # 扣完远程合作中余额,扣远程抵押中余额. 远程抵押中要扣除 deduct_pledge_amount = remote_deduct - user_asset.remote_4coop_asset if user_asset.available_asset >= deduct_pledge_amount: # 如果远程可用资产中能覆盖远程抵押扣除。添加本地抵押余额,减去远程抵押余额 user_asset.pledge_asset += deduct_pledge_amount user_asset.remote_4pledge_asset -= deduct_pledge_amount else: user_asset.pledge_asset += user_asset.available_asset user_asset.remote_4pledge_asset = user_asset.remote_freeze_asset user_asset.coop_freeze_asset -= user_asset.remote_4coop_asset user_asset.remote_4coop_asset = 0 user_asset.available_asset = 0 # 合作冻结资金修改,检查是否违约 if coop_freeze_asset != user_asset.coop_freeze_asset: # 进行中的订单 team_works = TeamWorkRecordActivity.query.filter_by( account_key=remote_pledge.account_key, status=TeamWorking).order_by( TeamWorkRecordActivity.create_time.asc( )).with_for_update(read=True).all() # 合作违约金额= 用户需要金额-剩余金额 gap_amount = coop_freeze_asset - user_asset.coop_freeze_asset if gap_amount > 0: # 实际抵押金额不满足需要金额 if team_works: security_deposit = remote_pledge_amount / 4 gap_amount += security_deposit for team_work in team_works: if gap_amount > 0: # 扣除违约订单,部分扣除的返还剩余部分。 team_work.status = BadTeamWork gap_amount -= team_work.coo_amount else: break # 扣除违约金 可用>合作>抵押 # 合作冻结中可扣 = 合作冻结 - 远程借贷合作 margin_in_coop = user_asset.coop_freeze_asset - user_asset.remote_4coop_asset deduct_local_pledge_amount = security_deposit - margin_in_coop if deduct_local_pledge_amount > 0: user_asset.pledge_asset -= deduct_local_pledge_amount user_asset.coop_freeze_asset = 0 else: user_asset.coop_freeze_asset -= security_deposit user_asset.total_asset -= security_deposit # 返还剩余部分 if gap_amount < 0: refund_amount = -gap_amount local_asset_in_coop = user_asset.get_local_in_coop( ) # 少的那一部分,全部返还到本地 refund_local = min(refund_amount, local_asset_in_coop) deduct_remote_pledge_asset = total_pledge_amount - user_asset.get_pledge_amount( ) if deduct_remote_pledge_asset >= refund_local: user_asset.pledge_asset += refund_local else: user_asset.pledge_asset += deduct_remote_pledge_asset user_asset.available_asset += ( refund_local - deduct_remote_pledge_asset) # 合作中本地部分少于返还部分,远程用于合作中返还 if local_asset_in_coop < refund_amount: user_asset.remote_4coop_asset -= ( refund_amount - local_asset_in_coop) # 减去订单中多扣除部分 user_asset.coop_freeze_asset -= refund_amount billing = Billings(user_asset.account_key, security_deposit, '', '', COOP_FINE) db.session.add(billing) celery_logger.info("deduct security deposit %s " % billing.to_dict()) celery_logger.info("user_asset after deduct %s" % user_asset.to_dict()) remote_pledge.status = DEBIT_UNDONE db.session.commit() except Exception as e: db.session.rollback() celery_logger.error("check pledge failed %s" % e)