Search in sources :

Example 1 with SerializationException

use of com.mobilecoin.lib.exceptions.SerializationException in project Signal-Android by WhisperSystems.

the class Wallet method sendPayment.

@WorkerThread
private void sendPayment(@NonNull MobileCoinPublicAddress to, @NonNull Money.MobileCoin amount, @NonNull Money.MobileCoin totalFee, boolean defragmentFirst, @NonNull List<TransactionSubmissionResult> results) {
    Money.MobileCoin defragmentFees = Money.MobileCoin.ZERO;
    if (defragmentFirst) {
        try {
            defragmentFees = defragment(amount, results);
        } catch (InsufficientFundsException e) {
            Log.w(TAG, "Insufficient funds", e);
            results.add(TransactionSubmissionResult.failure(TransactionSubmissionResult.ErrorCode.INSUFFICIENT_FUNDS, true));
            return;
        } catch (TimeoutException | InvalidTransactionException | InvalidFogResponse | AttestationException | TransactionBuilderException | NetworkException | FogReportException e) {
            Log.w(TAG, "Defragment failed", e);
            results.add(TransactionSubmissionResult.failure(TransactionSubmissionResult.ErrorCode.GENERIC_FAILURE, true));
            return;
        }
    }
    Money.MobileCoin feeMobileCoin = totalFee.subtract(defragmentFees).requireMobileCoin();
    BigInteger picoMob = amount.requireMobileCoin().toPicoMobBigInteger();
    PendingTransaction pendingTransaction = null;
    Log.i(TAG, String.format("Total fee advised: %s\nDefrag fees: %s\nTransaction fee: %s", totalFee, defragmentFees, feeMobileCoin));
    if (!feeMobileCoin.isPositive()) {
        Log.i(TAG, "No fee left after defrag");
        results.add(TransactionSubmissionResult.failure(TransactionSubmissionResult.ErrorCode.GENERIC_FAILURE, false));
        return;
    }
    try {
        pendingTransaction = mobileCoinClient.prepareTransaction(to.getAddress(), picoMob, feeMobileCoin.toPicoMobBigInteger());
    } catch (InsufficientFundsException e) {
        Log.w(TAG, "Insufficient funds", e);
        results.add(TransactionSubmissionResult.failure(TransactionSubmissionResult.ErrorCode.INSUFFICIENT_FUNDS, false));
    } catch (FeeRejectedException e) {
        Log.w(TAG, "Fee rejected " + totalFee, e);
        results.add(TransactionSubmissionResult.failure(TransactionSubmissionResult.ErrorCode.GENERIC_FAILURE, false));
    } catch (InvalidFogResponse | FogReportException e) {
        Log.w(TAG, "Invalid fog response", e);
        results.add(TransactionSubmissionResult.failure(TransactionSubmissionResult.ErrorCode.GENERIC_FAILURE, false));
    } catch (FragmentedAccountException e) {
        if (defragmentFirst) {
            Log.w(TAG, "Account is fragmented, but already tried to defragment", e);
            results.add(TransactionSubmissionResult.failure(TransactionSubmissionResult.ErrorCode.GENERIC_FAILURE, false));
        } else {
            Log.i(TAG, "Account is fragmented, defragmenting and retrying");
            sendPayment(to, amount, totalFee, true, results);
        }
    } catch (AttestationException e) {
        Log.w(TAG, "Attestation problem", e);
        results.add(TransactionSubmissionResult.failure(TransactionSubmissionResult.ErrorCode.GENERIC_FAILURE, false));
    } catch (NetworkException e) {
        Log.w(TAG, "Network problem", e);
        results.add(TransactionSubmissionResult.failure(TransactionSubmissionResult.ErrorCode.GENERIC_FAILURE, false));
    } catch (TransactionBuilderException e) {
        Log.w(TAG, "Builder problem", e);
        results.add(TransactionSubmissionResult.failure(TransactionSubmissionResult.ErrorCode.GENERIC_FAILURE, false));
    }
    if (pendingTransaction == null) {
        Log.w(TAG, "Failed to create pending transaction");
        return;
    }
    try {
        Log.i(TAG, "Submitting transaction");
        mobileCoinClient.submitTransaction(pendingTransaction.getTransaction());
        Log.i(TAG, "Transaction submitted");
        results.add(TransactionSubmissionResult.successfullySubmitted(new PaymentTransactionId.MobileCoin(pendingTransaction.getTransaction().toByteArray(), pendingTransaction.getReceipt().toByteArray(), feeMobileCoin)));
    } catch (NetworkException e) {
        Log.w(TAG, "Network problem", e);
        results.add(TransactionSubmissionResult.failure(TransactionSubmissionResult.ErrorCode.NETWORK_FAILURE, false));
    } catch (InvalidTransactionException e) {
        Log.w(TAG, "Invalid transaction", e);
        results.add(TransactionSubmissionResult.failure(TransactionSubmissionResult.ErrorCode.GENERIC_FAILURE, false));
    } catch (AttestationException e) {
        Log.w(TAG, "Attestation problem", e);
        results.add(TransactionSubmissionResult.failure(TransactionSubmissionResult.ErrorCode.GENERIC_FAILURE, false));
    } catch (SerializationException e) {
        Log.w(TAG, "Serialization problem", e);
        results.add(TransactionSubmissionResult.failure(TransactionSubmissionResult.ErrorCode.GENERIC_FAILURE, false));
    }
}
Also used : PendingTransaction(com.mobilecoin.lib.PendingTransaction) AttestationException(com.mobilecoin.lib.exceptions.AttestationException) FogReportException(com.mobilecoin.lib.exceptions.FogReportException) SerializationException(com.mobilecoin.lib.exceptions.SerializationException) FeeRejectedException(com.mobilecoin.lib.exceptions.FeeRejectedException) InvalidTransactionException(com.mobilecoin.lib.exceptions.InvalidTransactionException) InvalidFogResponse(com.mobilecoin.lib.exceptions.InvalidFogResponse) TransactionBuilderException(com.mobilecoin.lib.exceptions.TransactionBuilderException) Money(org.whispersystems.signalservice.api.payments.Money) FragmentedAccountException(com.mobilecoin.lib.exceptions.FragmentedAccountException) InsufficientFundsException(com.mobilecoin.lib.exceptions.InsufficientFundsException) BigInteger(java.math.BigInteger) NetworkException(com.mobilecoin.lib.exceptions.NetworkException) TimeoutException(java.util.concurrent.TimeoutException) WorkerThread(androidx.annotation.WorkerThread)

Example 2 with SerializationException

use of com.mobilecoin.lib.exceptions.SerializationException in project Signal-Android by WhisperSystems.

the class PaymentDatabase method markPaymentSubmitted.

public boolean markPaymentSubmitted(@NonNull UUID uuid, @NonNull byte[] transaction, @NonNull byte[] receipt, @NonNull Money fee) throws PublicKeyConflictException {
    SQLiteDatabase database = databaseHelper.getSignalWritableDatabase();
    String where = PAYMENT_UUID + " = ?";
    String[] whereArgs = { uuid.toString() };
    int updated;
    ContentValues values = new ContentValues(6);
    values.put(STATE, State.SUBMITTED.serialize());
    values.put(TRANSACTION, transaction);
    values.put(RECEIPT, receipt);
    try {
        values.put(PUBLIC_KEY, Base64.encodeBytes(PaymentMetaDataUtil.receiptPublic(PaymentMetaDataUtil.fromReceipt(receipt))));
        values.put(META_DATA, PaymentMetaDataUtil.fromReceiptAndTransaction(receipt, transaction).toByteArray());
    } catch (SerializationException e) {
        throw new IllegalArgumentException(e);
    }
    values.put(FEE, CryptoValueUtil.moneyToCryptoValue(fee).toByteArray());
    database.beginTransaction();
    try {
        updated = database.update(TABLE_NAME, values, where, whereArgs);
        if (updated == -1) {
            throw new PublicKeyConflictException();
        }
        if (updated > 1) {
            Log.w(TAG, "More than one row matches criteria");
            throw new AssertionError();
        }
        database.setTransactionSuccessful();
    } finally {
        database.endTransaction();
    }
    if (updated > 0) {
        notifyChanged(uuid);
    }
    return updated > 0;
}
Also used : ContentValues(android.content.ContentValues) SerializationException(com.mobilecoin.lib.exceptions.SerializationException)

Example 3 with SerializationException

use of com.mobilecoin.lib.exceptions.SerializationException in project Signal-Android by WhisperSystems.

the class MessageContentProcessor method handleSynchronizeOutgoingPayment.

private void handleSynchronizeOutgoingPayment(@NonNull SignalServiceContent content, @NonNull OutgoingPaymentMessage outgoingPaymentMessage) {
    RecipientId recipientId = outgoingPaymentMessage.getRecipient().transform(RecipientId::from).orNull();
    long timestamp = outgoingPaymentMessage.getBlockTimestamp();
    if (timestamp == 0) {
        timestamp = System.currentTimeMillis();
    }
    Optional<MobileCoinPublicAddress> address = outgoingPaymentMessage.getAddress().transform(MobileCoinPublicAddress::fromBytes);
    if (!address.isPresent() && recipientId == null) {
        log(content.getTimestamp(), "Inserting defrag");
        address = Optional.of(ApplicationDependencies.getPayments().getWallet().getMobileCoinPublicAddress());
        recipientId = Recipient.self().getId();
    }
    UUID uuid = UUID.randomUUID();
    try {
        SignalDatabase.payments().createSuccessfulPayment(uuid, recipientId, address.get(), timestamp, outgoingPaymentMessage.getBlockIndex(), outgoingPaymentMessage.getNote().or(""), outgoingPaymentMessage.getAmount(), outgoingPaymentMessage.getFee(), outgoingPaymentMessage.getReceipt().toByteArray(), PaymentMetaDataUtil.fromKeysAndImages(outgoingPaymentMessage.getPublicKeys(), outgoingPaymentMessage.getKeyImages()));
    } catch (SerializationException e) {
        warn(content.getTimestamp(), "Ignoring synchronized outgoing payment with bad data.", e);
    }
    log("Inserted synchronized payment " + uuid);
}
Also used : RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) SerializationException(com.mobilecoin.lib.exceptions.SerializationException) UUID(java.util.UUID) MobileCoinPublicAddress(org.thoughtcrime.securesms.payments.MobileCoinPublicAddress)

Example 4 with SerializationException

use of com.mobilecoin.lib.exceptions.SerializationException in project Signal-Android by WhisperSystems.

the class MessageContentProcessor method handlePayment.

private void handlePayment(@NonNull SignalServiceContent content, @NonNull SignalServiceDataMessage message, @NonNull Recipient senderRecipient) {
    log(content.getTimestamp(), "Payment message.");
    if (!message.getPayment().isPresent()) {
        throw new AssertionError();
    }
    if (!message.getPayment().get().getPaymentNotification().isPresent()) {
        warn(content.getTimestamp(), "Ignoring payment message without notification");
        return;
    }
    SignalServiceDataMessage.PaymentNotification paymentNotification = message.getPayment().get().getPaymentNotification().get();
    PaymentDatabase paymentDatabase = SignalDatabase.payments();
    UUID uuid = UUID.randomUUID();
    String queue = "Payment_" + PushProcessMessageJob.getQueueName(senderRecipient.getId());
    try {
        paymentDatabase.createIncomingPayment(uuid, senderRecipient.getId(), message.getTimestamp(), paymentNotification.getNote(), Money.MobileCoin.ZERO, Money.MobileCoin.ZERO, paymentNotification.getReceipt());
    } catch (PaymentDatabase.PublicKeyConflictException e) {
        warn(content.getTimestamp(), "Ignoring payment with public key already in database");
        return;
    } catch (SerializationException e) {
        warn(content.getTimestamp(), "Ignoring payment with bad data.", e);
    }
    ApplicationDependencies.getJobManager().startChain(new PaymentTransactionCheckJob(uuid, queue)).then(PaymentLedgerUpdateJob.updateLedger()).enqueue();
}
Also used : SignalServiceDataMessage(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage) SerializationException(com.mobilecoin.lib.exceptions.SerializationException) PaymentDatabase(org.thoughtcrime.securesms.database.PaymentDatabase) UUID(java.util.UUID) PaymentTransactionCheckJob(org.thoughtcrime.securesms.jobs.PaymentTransactionCheckJob)

Example 5 with SerializationException

use of com.mobilecoin.lib.exceptions.SerializationException in project Signal-Android by signalapp.

the class PaymentDatabase method markPaymentSubmitted.

public boolean markPaymentSubmitted(@NonNull UUID uuid, @NonNull byte[] transaction, @NonNull byte[] receipt, @NonNull Money fee) throws PublicKeyConflictException {
    SQLiteDatabase database = databaseHelper.getSignalWritableDatabase();
    String where = PAYMENT_UUID + " = ?";
    String[] whereArgs = { uuid.toString() };
    int updated;
    ContentValues values = new ContentValues(6);
    values.put(STATE, State.SUBMITTED.serialize());
    values.put(TRANSACTION, transaction);
    values.put(RECEIPT, receipt);
    try {
        values.put(PUBLIC_KEY, Base64.encodeBytes(PaymentMetaDataUtil.receiptPublic(PaymentMetaDataUtil.fromReceipt(receipt))));
        values.put(META_DATA, PaymentMetaDataUtil.fromReceiptAndTransaction(receipt, transaction).toByteArray());
    } catch (SerializationException e) {
        throw new IllegalArgumentException(e);
    }
    values.put(FEE, CryptoValueUtil.moneyToCryptoValue(fee).toByteArray());
    database.beginTransaction();
    try {
        updated = database.update(TABLE_NAME, values, where, whereArgs);
        if (updated == -1) {
            throw new PublicKeyConflictException();
        }
        if (updated > 1) {
            Log.w(TAG, "More than one row matches criteria");
            throw new AssertionError();
        }
        database.setTransactionSuccessful();
    } finally {
        database.endTransaction();
    }
    if (updated > 0) {
        notifyChanged(uuid);
    }
    return updated > 0;
}
Also used : ContentValues(android.content.ContentValues) SerializationException(com.mobilecoin.lib.exceptions.SerializationException)

Aggregations

SerializationException (com.mobilecoin.lib.exceptions.SerializationException)12 WorkerThread (androidx.annotation.WorkerThread)6 AttestationException (com.mobilecoin.lib.exceptions.AttestationException)6 InvalidFogResponse (com.mobilecoin.lib.exceptions.InvalidFogResponse)6 NetworkException (com.mobilecoin.lib.exceptions.NetworkException)6 NonNull (androidx.annotation.NonNull)4 PendingTransaction (com.mobilecoin.lib.PendingTransaction)4 IOException (java.io.IOException)4 BigInteger (java.math.BigInteger)4 UUID (java.util.UUID)4 ContentValues (android.content.ContentValues)2 Receipt (com.mobilecoin.lib.Receipt)2 Transaction (com.mobilecoin.lib.Transaction)2 AmountDecoderException (com.mobilecoin.lib.exceptions.AmountDecoderException)2 FeeRejectedException (com.mobilecoin.lib.exceptions.FeeRejectedException)2 FogReportException (com.mobilecoin.lib.exceptions.FogReportException)2 FragmentedAccountException (com.mobilecoin.lib.exceptions.FragmentedAccountException)2 InsufficientFundsException (com.mobilecoin.lib.exceptions.InsufficientFundsException)2 InvalidReceiptException (com.mobilecoin.lib.exceptions.InvalidReceiptException)2 InvalidTransactionException (com.mobilecoin.lib.exceptions.InvalidTransactionException)2