Beispiel #1
0
def calculate_activity_reward():
    rewards = ActivityReward.query.filter_by(is_add_asset=0).all()
    if not rewards:
        return
    for reward in rewards:
        try:
            income_num = reward.query.filter_by(
                id=reward.id,
                is_add_asset=0).update({ActivityReward.is_add_asset: 1})
            if income_num == 0:
                continue
            user_asset = UserAsset.query.filter_by(
                account_key=reward.account_key).with_for_update(
                    read=True).first()
            if not user_asset:
                continue
            # 添加用户资产
            if reward.amount > 0:
                user_asset.available_asset += reward.amount
                user_asset.total_asset += reward.amount
            billing = Billings(user_asset.account_key, reward.amount, '', '',
                               ACTIVITY_REWORD)
            db.session.add(billing)
            celery_logger.info("user:%s, income %s " %
                               (user_asset.to_dict(), reward.to_dict()))
            db.session.commit()
        except Exception as e:
            celery_logger.error("calculate_activity_reward error:%s" % str(e))
            db.session.rollback()
Beispiel #2
0
def calculate_income_ecol():
    # 查询未统计收益
    latest_height = bhd_client.get_latest_block_number()
    mature_height = latest_height - 6
    not_add_incomes = IncomeEcologyRecord.query.filter(
        and_(IncomeEcologyRecord.is_add_asset == 0,
             IncomeEcologyRecord.height > mature_height))
    for income in not_add_incomes:
        try:
            income_num = income.query.filter_by(
                id=income.id,
                is_add_asset=0).update({IncomeRecord.is_add_asset: 1})
            if income_num == 0:
                continue
            user_asset = UserAsset.query.filter_by(
                account_key=income.account_key,
                coin_name=BHD_COIN_NAME).with_for_update(read=False).first()
            if not user_asset:
                continue
            # 添加用户资产
            user_asset.available_asset += income.amount
            user_asset.total_asset += income.amount
            billing = Billings(user_asset.account_key,
                               income.amount,
                               '',
                               '',
                               ECOL_MINE_EARNINGS,
                               create_time=income.create_time)
            db.session.add(billing)
            celery_logger.info("user:%s, income %s " %
                               (user_asset.to_dict(), income.to_dict()))
            db.session.commit()
        except Exception as e:
            celery_logger.error("calculate_income error:%s" % str(e))
            db.session.rollback()
def statistic_pledges():
    """
    检查链上借贷交易,并给用户添加借贷资产
    :return:
    """
    pledges = bhd_client.list_pledges()
    if not pledges:
        return
    for pledge in pledges:
        amount = pledge['amount']
        blockheight = pledge['blockheight']
        category = pledge['category']
        from_address = pledge['from']
        to_address = pledge['to']
        txid = pledge['txid']
        valid = pledge['valid']

        if not valid:
            continue
        if category != "debit":
            continue
        if to_address != BHD_MINER_ADDRESS:
            continue
        remote_pledge_address = RemotePledgeAddress.query.filter_by(
            address=from_address).first()
        if not remote_pledge_address:
            celery_logger.info("pledge address not found: %s" % from_address)
            continue
        pledge_tr = RemotePledgeTransaction.query.filter_by(
            pledge_txid=txid).first()
        if pledge_tr:
            continue
        account_key = remote_pledge_address.account_key
        user_asset = UserAsset.query.filter_by(
            account_key=account_key,
            coin_name=BHD_COIN_NAME).with_for_update(read=True).first()
        if not user_asset:
            raise Exception("account_key:%s not found, address:%s" %
                            (account_key, from_address))
        pledge_margin = user_asset.get_available_margin_amount()
        if amount / 4 > pledge_margin:
            # 抵押保证金不足,不予抵押
            continue
        try:
            # 添加远程抵押记录
            user_asset.remote_freeze_asset += amount
            pledge_tr = RemotePledgeTransaction(account_key, from_address,
                                                amount, blockheight, txid)
            db.session.add(pledge_tr)
            db.session.commit()
            celery_logger.info("pledge success %s" % pledge_tr.to_dict())
        except Exception as e:
            db.session.rollback()
            celery_logger.error("pledge failed %s" % e)
Beispiel #4
0
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)
Beispiel #5
0
def withdrawal_confirm():
    withdrawal_sendings = WithdrawalTransaction.query.filter_by(
        status=WITHDRAWAL_SENDING).all()
    if not withdrawal_sendings:
        return

    for withdrawal_sending in withdrawal_sendings:
        client = get_rpc(withdrawal_sending.coin_name)
        detail = client.get_transaction_detail(withdrawal_sending.txid)
        confirmed = detail.get('confirmations', 0)
        if confirmed > MIN_CONFIRMED[withdrawal_sending.coin_name]:
            try:
                withdrawal_sending.status = WITHDRAWAL_SENDED
                celery_logger.info("withdrawal confirmed %s " %
                                   withdrawal_sending.to_dict())
                db.session.commit()
            except Exception as e:
                db.session.rollback()
                celery_logger.error("withdrawal confirmed, error %s" % str(e))
Beispiel #6
0
def deposit_add_asset():
    confirmed_deposit_transactions = DepositTranscation.query.filter_by(
        status=DEPOSIT_CONFIRMED).all()
    if not confirmed_deposit_transactions:
        return
    for transaction in confirmed_deposit_transactions:
        try:
            user_asset = UserAsset.query.filter_by(
                account_key=transaction.account_key,
                coin_name=transaction.coin_name).with_for_update(
                read=True).first()
            user_asset.available_asset += transaction.amount
            user_asset.total_asset += transaction.amount
            transaction.status = DEPOSIT_ADDED
            celery_logger.info(
                "deposit update asset %s " % transaction.to_dict())
            db.session.commit()
        except Exception as e:
            db.session.rollback()
            celery_logger.error("deposit_add_asset task, error %s" % str(e))
            continue
Beispiel #7
0
def withdrawal_coin():
    withdrawal_applys = WithdrawalTransaction.query.filter_by(
        status=WITHDRAWAL_PASS).all()
    if not withdrawal_applys:
        return
    for withdrawal_apply in withdrawal_applys:
        account_key = withdrawal_apply.account_key

        try:
            user_asset = UserAsset.query.filter_by(
                account_key=account_key,
                coin_name=withdrawal_apply.coin_name).with_for_update(
                    read=True).first()
            assert user_asset
            assert withdrawal_apply.amount <= user_asset.frozen_asset
            assert withdrawal_apply.amount <= user_asset.total_asset - user_asset.available_asset - user_asset.trading_asset - user_asset.pledge_asset

            if withdrawal_apply.coin_name == 'lhd':
                client = lhd_client_main
            else:
                client = get_rpc(withdrawal_apply.coin_name)
            txid = client.withdrawal(withdrawal_apply.to_address,
                                     withdrawal_apply.actual_amount)
            status = WITHDRAWAL_SENDING
            user_asset.frozen_asset -= withdrawal_apply.amount
            user_asset.total_asset -= withdrawal_apply.amount
        except Exception as e:
            celery_logger.error("withdrawal task,withdrawal error %s" % str(e))
            txid = 0
            status = WITHDRAWAL_FAILED
        try:
            withdrawal_apply.txid = txid
            withdrawal_apply.status = status
            db.session.commit()
            celery_logger.info("withdrawal task success, %s" %
                               withdrawal_apply.to_dict())
        except Exception as e:
            db.session.rollback()
            celery_logger.error("withdrawal task, error %s" % str(e))
            continue
Beispiel #8
0
def nb_calculate_income():
    # 查询未统计收益
    latest_height = nb_client.get_latest_block_number()
    mature_height = latest_height - 6
    not_add_incomes = NBIncomeRecord.query.filter(
        and_(NBIncomeRecord.is_add_asset == 0,
             NBIncomeRecord.height < mature_height)).all()
    for income in not_add_incomes:
        try:
            income_num = income.query.filter_by(
                id=income.id,
                is_add_asset=0).update({NBIncomeRecord.is_add_asset: 1})
            if income_num == 0:
                continue

            user_asset = UserAsset.query.filter_by(
                account_key=income.account_key,
                coin_name=NEWBI_NAME).with_for_update(read=False).first()
            # 添加用户资产
            if not user_asset:
                continue
            user_asset.available_asset += income.amount
            user_asset.total_asset += income.amount
            # income.update(is_add_asset=1).where(id=income.id, is_add_asset=0)
            celery_logger.info("user:%s, income %s " %
                               (user_asset.to_dict(), income.to_dict()))
            income_type = MINING_COOPERATION
            if income.type == IncomeTYpeCoopReward:
                income_type = COOP_MINE_EARNINGS
            billing = Billings(user_asset.account_key,
                               income.amount,
                               '',
                               '',
                               income_type,
                               create_time=income.create_time)
            db.session.add(billing)
            db.session.commit()
        except Exception as e:
            celery_logger.error("calculate_income error:%s" % str(e))
            db.session.rollback()
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)