예제 #1
0
def test_deposit_stellar_success(
    mock_submit, mock_base_fee, client, acc1_usd_deposit_transaction_factory,
):
    """
    `create_stellar_deposit` succeeds if the provided transaction's `stellar_account`
    has a trustline to the issuer for its `asset`, and the Stellar transaction completes
    successfully. All of these conditions and actions are mocked in this test to avoid
    network calls.
    """
    del mock_submit, mock_base_fee, client
    deposit = acc1_usd_deposit_transaction_factory()
    deposit.status = Transaction.STATUS.pending_anchor
    deposit.save()
    create_stellar_deposit(deposit.id)
    assert Transaction.objects.get(id=deposit.id).status == Transaction.STATUS.completed
예제 #2
0
def test_deposit_stellar_no_trustline(
    mock_submit, mock_base_fee, client, acc1_usd_deposit_transaction_factory,
):
    """
    `create_stellar_deposit` sets the transaction with the provided `transaction_id` to
    status `pending_trust` if the provided transaction's Stellar account has no trustline
    for its asset. (We assume the asset's issuer is the server Stellar account.)
    """
    del mock_submit, mock_base_fee, client
    deposit = acc1_usd_deposit_transaction_factory()
    deposit.status = Transaction.STATUS.pending_anchor
    deposit.save()
    create_stellar_deposit(deposit.id)
    assert (
        Transaction.objects.get(id=deposit.id).status
        == Transaction.STATUS.pending_trust
    )
예제 #3
0
def test_deposit_stellar_no_account(
    mock_load_account, mock_base_fee, client, acc1_usd_deposit_transaction_factory,
):
    """
    `create_stellar_deposit` sets the transaction with the provided `transaction_id` to
    status `pending_trust` if the provided transaction's `stellar_account` does not
    exist yet. This condition is mocked by throwing an error when attempting to load
    information for the provided account.
    Normally, this function creates the account. We have mocked out that functionality,
    as it relies on network calls to Horizon.
    """
    del mock_load_account, mock_base_fee, client
    deposit = acc1_usd_deposit_transaction_factory()
    deposit.status = Transaction.STATUS.pending_anchor
    deposit.save()
    create_stellar_deposit(deposit.id)
    assert (
        Transaction.objects.get(id=deposit.id).status
        == Transaction.STATUS.pending_trust
    )
예제 #4
0
 def check_trustlines():
     """
     Create Stellar transaction for deposit transactions marked as pending trust, if a
     trustline has been created.
     """
     transactions = Transaction.objects.filter(
         kind=Transaction.KIND.deposit,
         status=Transaction.STATUS.pending_trust)
     server = settings.HORIZON_SERVER
     for transaction in transactions:
         try:
             account = (server.accounts().account_id(
                 transaction.stellar_account).call())
         except BaseHorizonError:
             logger.warning(
                 f"could not load account {transaction.stellar_account} using provided horizon URL"
             )
             continue
         try:
             balances = account["balances"]
         except KeyError:
             logger.debug(
                 f"horizon account {transaction.stellar_account} response had no balances"
             )
             continue
         for balance in balances:
             try:
                 asset_code = balance["asset_code"]
                 asset_issuer = balance["asset_issuer"]
             except KeyError:
                 logger.debug(
                     f"Unable to retrieve asset info from balance object: {balance}"
                 )
                 if balance.get("asset_type") != "native":
                     logger.debug(
                         f"horizon balance had no asset_code for account {account['id']}"
                     )
                 continue
             if (asset_code == transaction.asset.code
                     and asset_issuer == transaction.asset.issuer):
                 logger.info(
                     f"Account {account['id']} has established a trustline for {asset_code}, "
                     f"initiating deposit for {transaction.id}")
                 if create_stellar_deposit(transaction.id):
                     transaction.refresh_from_db()
                     try:
                         rdi.after_deposit(transaction)
                     except Exception:
                         logger.exception(
                             "An unexpected error was raised from "
                             "after_deposit() in check_trustlines")
예제 #5
0
def execute_deposit(transaction: Transaction) -> bool:
    """
    The external deposit has been completed, so the transaction
    status must now be updated to *pending_anchor*. Executes the
    transaction by calling :func:`create_stellar_deposit`.

    :param transaction: the transaction to be executed
    :returns a boolean of whether or not the transaction was
        completed successfully on the Stellar network.
    """
    if transaction.kind != transaction.KIND.deposit:
        raise ValueError("Transaction not a deposit")
    elif transaction.status != transaction.STATUS.pending_user_transfer_start:
        raise ValueError(
            f"Unexpected transaction status: {transaction.status}, expecting "
            f"{transaction.STATUS.pending_user_transfer_start}")
    transaction.status = Transaction.STATUS.pending_anchor
    transaction.status_eta = 5  # Ledger close time.
    transaction.save()
    # launch the deposit Stellar transaction.
    return create_stellar_deposit(transaction.id)
 def create_stellar_deposit(transaction_id):
     """Create and submit the Stellar transaction for the deposit."""
     try:
         create_stellar_deposit(transaction_id)
     except Exception as e:
         raise CommandError(e)