Search in sources :

Example 1 with ReconstructedPayment

use of org.thoughtcrime.securesms.payments.ReconstructedPayment in project Signal-Android by WhisperSystems.

the class LedgerReconcile method reconcile.

@WorkerThread
@NonNull
private static List<Payment> reconcile(@NonNull Collection<? extends Payment> allLocalPaymentTransactions, @NonNull List<MobileCoinLedgerWrapper.OwnedTxo> allTxOuts) {
    List<? extends Payment> nonFailedLocalPayments = Stream.of(allLocalPaymentTransactions).filter(i -> i.getState() != State.FAILED).toList();
    Set<ByteString> allKnownPublicKeys = new HashSet<>(nonFailedLocalPayments.size());
    Set<ByteString> allKnownKeyImages = new HashSet<>(nonFailedLocalPayments.size());
    for (Payment paymentTransaction : nonFailedLocalPayments) {
        PaymentMetaData.MobileCoinTxoIdentification txoIdentification = paymentTransaction.getPaymentMetaData().getMobileCoinTxoIdentification();
        allKnownPublicKeys.addAll(txoIdentification.getPublicKeyList());
        allKnownKeyImages.addAll(txoIdentification.getKeyImagesList());
    }
    Set<MobileCoinLedgerWrapper.OwnedTxo> knownTxosByKeyImage = Stream.of(allTxOuts).filter(t -> allKnownKeyImages.contains(t.getKeyImage())).collect(Collectors.toSet());
    Set<MobileCoinLedgerWrapper.OwnedTxo> knownTxosByPublicKeys = Stream.of(allTxOuts).filter(t -> allKnownPublicKeys.contains(t.getPublicKey())).collect(Collectors.toSet());
    // any TXO that we can't pair up the pub key for, we don't have detail for how it got into the account
    Set<MobileCoinLedgerWrapper.OwnedTxo> unknownTxOutsReceived = new HashSet<>(allTxOuts);
    unknownTxOutsReceived.removeAll(knownTxosByPublicKeys);
    // any TXO that we can't pair up the keyimage for, we don't have detail for how it got spent
    Set<MobileCoinLedgerWrapper.OwnedTxo> unknownTxOutsSpent = Stream.of(allTxOuts).filter(MobileCoinLedgerWrapper.OwnedTxo::isSpent).collect(Collectors.toSet());
    unknownTxOutsSpent.removeAll(knownTxosByKeyImage);
    if (unknownTxOutsReceived.isEmpty() && unknownTxOutsSpent.isEmpty()) {
        return Stream.of(allLocalPaymentTransactions).map(t -> (Payment) t).toList();
    }
    List<DetailedTransaction> detailedTransactions = reconstructAllTransactions(unknownTxOutsReceived, unknownTxOutsSpent);
    List<Payment> reconstructedPayments = new ArrayList<>(detailedTransactions.size());
    List<Payment> blockDecoratedLocalPayments = decoratePaymentsWithBlockIndexes(allLocalPaymentTransactions, allTxOuts);
    for (DetailedTransaction detailedTransaction : detailedTransactions) {
        reconstructedPayments.add(new ReconstructedPayment(detailedTransaction.blockDetail.getBlockIndex(), detailedTransaction.blockDetail.getBlockTimestampOrZero(), detailedTransaction.transaction.getDirection(), detailedTransaction.transaction.getValue()));
    }
    Collections.sort(reconstructedPayments, Payment.DESCENDING_BLOCK_INDEX);
    return ZipList.zipList(blockDecoratedLocalPayments, reconstructedPayments, Payment.DESCENDING_BLOCK_INDEX_UNKNOWN_FIRST);
}
Also used : PaymentMetaData(org.thoughtcrime.securesms.payments.proto.PaymentMetaData) PaymentDecorator(org.thoughtcrime.securesms.payments.PaymentDecorator) MapUtil(org.signal.core.util.MapUtil) Stream(com.annimon.stream.Stream) NonNull(androidx.annotation.NonNull) MobileCoinLedgerWrapper(org.thoughtcrime.securesms.payments.MobileCoinLedgerWrapper) WorkerThread(androidx.annotation.WorkerThread) HashMap(java.util.HashMap) ComparatorCompat(com.annimon.stream.ComparatorCompat) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) Locale(java.util.Locale) Map(java.util.Map) TransactionReconstruction(org.thoughtcrime.securesms.payments.history.TransactionReconstruction) Nullable(javax.annotation.Nullable) State(org.thoughtcrime.securesms.payments.State) Collectors(com.annimon.stream.Collectors) Collection(java.util.Collection) Set(java.util.Set) ByteString(com.google.protobuf.ByteString) Log(org.signal.core.util.logging.Log) List(java.util.List) ReconstructedPayment(org.thoughtcrime.securesms.payments.ReconstructedPayment) Payment(org.thoughtcrime.securesms.payments.Payment) Comparator(java.util.Comparator) Collections(java.util.Collections) Money(org.whispersystems.signalservice.api.payments.Money) PaymentMetaData(org.thoughtcrime.securesms.payments.proto.PaymentMetaData) ByteString(com.google.protobuf.ByteString) ArrayList(java.util.ArrayList) ReconstructedPayment(org.thoughtcrime.securesms.payments.ReconstructedPayment) MobileCoinLedgerWrapper(org.thoughtcrime.securesms.payments.MobileCoinLedgerWrapper) ReconstructedPayment(org.thoughtcrime.securesms.payments.ReconstructedPayment) Payment(org.thoughtcrime.securesms.payments.Payment) HashSet(java.util.HashSet) WorkerThread(androidx.annotation.WorkerThread) NonNull(androidx.annotation.NonNull)

Example 2 with ReconstructedPayment

use of org.thoughtcrime.securesms.payments.ReconstructedPayment in project Signal-Android by signalapp.

the class LedgerReconcile method reconcile.

@WorkerThread
@NonNull
private static List<Payment> reconcile(@NonNull Collection<? extends Payment> allLocalPaymentTransactions, @NonNull List<MobileCoinLedgerWrapper.OwnedTxo> allTxOuts) {
    List<? extends Payment> nonFailedLocalPayments = Stream.of(allLocalPaymentTransactions).filter(i -> i.getState() != State.FAILED).toList();
    Set<ByteString> allKnownPublicKeys = new HashSet<>(nonFailedLocalPayments.size());
    Set<ByteString> allKnownKeyImages = new HashSet<>(nonFailedLocalPayments.size());
    for (Payment paymentTransaction : nonFailedLocalPayments) {
        PaymentMetaData.MobileCoinTxoIdentification txoIdentification = paymentTransaction.getPaymentMetaData().getMobileCoinTxoIdentification();
        allKnownPublicKeys.addAll(txoIdentification.getPublicKeyList());
        allKnownKeyImages.addAll(txoIdentification.getKeyImagesList());
    }
    Set<MobileCoinLedgerWrapper.OwnedTxo> knownTxosByKeyImage = Stream.of(allTxOuts).filter(t -> allKnownKeyImages.contains(t.getKeyImage())).collect(Collectors.toSet());
    Set<MobileCoinLedgerWrapper.OwnedTxo> knownTxosByPublicKeys = Stream.of(allTxOuts).filter(t -> allKnownPublicKeys.contains(t.getPublicKey())).collect(Collectors.toSet());
    // any TXO that we can't pair up the pub key for, we don't have detail for how it got into the account
    Set<MobileCoinLedgerWrapper.OwnedTxo> unknownTxOutsReceived = new HashSet<>(allTxOuts);
    unknownTxOutsReceived.removeAll(knownTxosByPublicKeys);
    // any TXO that we can't pair up the keyimage for, we don't have detail for how it got spent
    Set<MobileCoinLedgerWrapper.OwnedTxo> unknownTxOutsSpent = Stream.of(allTxOuts).filter(MobileCoinLedgerWrapper.OwnedTxo::isSpent).collect(Collectors.toSet());
    unknownTxOutsSpent.removeAll(knownTxosByKeyImage);
    if (unknownTxOutsReceived.isEmpty() && unknownTxOutsSpent.isEmpty()) {
        return Stream.of(allLocalPaymentTransactions).map(t -> (Payment) t).toList();
    }
    List<DetailedTransaction> detailedTransactions = reconstructAllTransactions(unknownTxOutsReceived, unknownTxOutsSpent);
    List<Payment> reconstructedPayments = new ArrayList<>(detailedTransactions.size());
    List<Payment> blockDecoratedLocalPayments = decoratePaymentsWithBlockIndexes(allLocalPaymentTransactions, allTxOuts);
    for (DetailedTransaction detailedTransaction : detailedTransactions) {
        reconstructedPayments.add(new ReconstructedPayment(detailedTransaction.blockDetail.getBlockIndex(), detailedTransaction.blockDetail.getBlockTimestampOrZero(), detailedTransaction.transaction.getDirection(), detailedTransaction.transaction.getValue()));
    }
    Collections.sort(reconstructedPayments, Payment.DESCENDING_BLOCK_INDEX);
    return ZipList.zipList(blockDecoratedLocalPayments, reconstructedPayments, Payment.DESCENDING_BLOCK_INDEX_UNKNOWN_FIRST);
}
Also used : PaymentMetaData(org.thoughtcrime.securesms.payments.proto.PaymentMetaData) PaymentDecorator(org.thoughtcrime.securesms.payments.PaymentDecorator) MapUtil(org.signal.core.util.MapUtil) Stream(com.annimon.stream.Stream) NonNull(androidx.annotation.NonNull) MobileCoinLedgerWrapper(org.thoughtcrime.securesms.payments.MobileCoinLedgerWrapper) WorkerThread(androidx.annotation.WorkerThread) HashMap(java.util.HashMap) ComparatorCompat(com.annimon.stream.ComparatorCompat) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) Locale(java.util.Locale) Map(java.util.Map) TransactionReconstruction(org.thoughtcrime.securesms.payments.history.TransactionReconstruction) Nullable(javax.annotation.Nullable) State(org.thoughtcrime.securesms.payments.State) Collectors(com.annimon.stream.Collectors) Collection(java.util.Collection) Set(java.util.Set) ByteString(com.google.protobuf.ByteString) Log(org.signal.core.util.logging.Log) List(java.util.List) ReconstructedPayment(org.thoughtcrime.securesms.payments.ReconstructedPayment) Payment(org.thoughtcrime.securesms.payments.Payment) Comparator(java.util.Comparator) Collections(java.util.Collections) Money(org.whispersystems.signalservice.api.payments.Money) PaymentMetaData(org.thoughtcrime.securesms.payments.proto.PaymentMetaData) ByteString(com.google.protobuf.ByteString) ArrayList(java.util.ArrayList) ReconstructedPayment(org.thoughtcrime.securesms.payments.ReconstructedPayment) MobileCoinLedgerWrapper(org.thoughtcrime.securesms.payments.MobileCoinLedgerWrapper) ReconstructedPayment(org.thoughtcrime.securesms.payments.ReconstructedPayment) Payment(org.thoughtcrime.securesms.payments.Payment) HashSet(java.util.HashSet) WorkerThread(androidx.annotation.WorkerThread) NonNull(androidx.annotation.NonNull)

Aggregations

NonNull (androidx.annotation.NonNull)2 WorkerThread (androidx.annotation.WorkerThread)2 Collectors (com.annimon.stream.Collectors)2 ComparatorCompat (com.annimon.stream.ComparatorCompat)2 Stream (com.annimon.stream.Stream)2 ByteString (com.google.protobuf.ByteString)2 ArrayList (java.util.ArrayList)2 Collection (java.util.Collection)2 Collections (java.util.Collections)2 Comparator (java.util.Comparator)2 HashMap (java.util.HashMap)2 HashSet (java.util.HashSet)2 List (java.util.List)2 Locale (java.util.Locale)2 Map (java.util.Map)2 Set (java.util.Set)2 Nullable (javax.annotation.Nullable)2 MapUtil (org.signal.core.util.MapUtil)2 Log (org.signal.core.util.logging.Log)2 MobileCoinLedgerWrapper (org.thoughtcrime.securesms.payments.MobileCoinLedgerWrapper)2