mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-21 11:38:36 +00:00
Fix payment notification backup import/export.
This commit is contained in:
@@ -503,7 +503,7 @@ class ChatItemExportIterator(private val cursor: Cursor, private val batchSize:
|
|||||||
PaymentNotification(
|
PaymentNotification(
|
||||||
amountMob = payment.amount.serializeAmountString(),
|
amountMob = payment.amount.serializeAmountString(),
|
||||||
feeMob = payment.fee.serializeAmountString(),
|
feeMob = payment.fee.serializeAmountString(),
|
||||||
note = payment.note,
|
note = payment.note.takeUnless { it.isEmpty() },
|
||||||
transactionDetails = payment.getTransactionDetails()
|
transactionDetails = payment.getTransactionDetails()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -789,16 +789,18 @@ class ChatItemExportIterator(private val cursor: Cursor, private val batchSize:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun PaymentTable.PaymentTransaction.getTransactionDetails(): PaymentNotification.TransactionDetails? {
|
private fun PaymentTable.PaymentTransaction.getTransactionDetails(): PaymentNotification.TransactionDetails? {
|
||||||
if (failureReason != null || state == State.FAILED) {
|
if (this.failureReason != null || this.state == State.FAILED) {
|
||||||
return PaymentNotification.TransactionDetails(failedTransaction = PaymentNotification.TransactionDetails.FailedTransaction(reason = failureReason.toBackupFailureReason()))
|
return PaymentNotification.TransactionDetails(failedTransaction = PaymentNotification.TransactionDetails.FailedTransaction(reason = this.failureReason.toBackupFailureReason()))
|
||||||
}
|
}
|
||||||
return PaymentNotification.TransactionDetails(
|
return PaymentNotification.TransactionDetails(
|
||||||
transaction = PaymentNotification.TransactionDetails.Transaction(
|
transaction = PaymentNotification.TransactionDetails.Transaction(
|
||||||
status = this.state.toBackupState(),
|
status = this.state.toBackupState(),
|
||||||
timestamp = timestamp,
|
timestamp = this.timestamp,
|
||||||
blockIndex = blockIndex,
|
blockIndex = this.blockIndex,
|
||||||
blockTimestamp = blockTimestamp,
|
blockTimestamp = this.blockTimestamp,
|
||||||
mobileCoinIdentification = paymentMetaData.mobileCoinTxoIdentification?.toBackup()
|
mobileCoinIdentification = this.paymentMetaData.mobileCoinTxoIdentification?.toBackup(),
|
||||||
|
transaction = this.transaction?.toByteString(),
|
||||||
|
receipt = this.receipt?.toByteString()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ import org.thoughtcrime.securesms.database.model.databaseprotos.ThreadMergeEvent
|
|||||||
import org.thoughtcrime.securesms.mms.QuoteModel
|
import org.thoughtcrime.securesms.mms.QuoteModel
|
||||||
import org.thoughtcrime.securesms.payments.CryptoValueUtil
|
import org.thoughtcrime.securesms.payments.CryptoValueUtil
|
||||||
import org.thoughtcrime.securesms.payments.Direction
|
import org.thoughtcrime.securesms.payments.Direction
|
||||||
|
import org.thoughtcrime.securesms.payments.FailureReason
|
||||||
import org.thoughtcrime.securesms.payments.State
|
import org.thoughtcrime.securesms.payments.State
|
||||||
import org.thoughtcrime.securesms.payments.proto.PaymentMetaData
|
import org.thoughtcrime.securesms.payments.proto.PaymentMetaData
|
||||||
import org.thoughtcrime.securesms.profiles.ProfileName
|
import org.thoughtcrime.securesms.profiles.ProfileName
|
||||||
@@ -494,6 +495,7 @@ class ChatItemImportInserter(
|
|||||||
chatRecipientId,
|
chatRecipientId,
|
||||||
transaction.timestamp ?: 0,
|
transaction.timestamp ?: 0,
|
||||||
transaction.blockIndex ?: 0,
|
transaction.blockIndex ?: 0,
|
||||||
|
transaction.blockTimestamp ?: 0,
|
||||||
paymentNotification.note ?: "",
|
paymentNotification.note ?: "",
|
||||||
if (chatItem.outgoing != null) Direction.SENT else Direction.RECEIVED,
|
if (chatItem.outgoing != null) Direction.SENT else Direction.RECEIVED,
|
||||||
transaction.status.toLocalStatus(),
|
transaction.status.toLocalStatus(),
|
||||||
@@ -502,7 +504,8 @@ class ChatItemImportInserter(
|
|||||||
transaction.transaction?.toByteArray(),
|
transaction.transaction?.toByteArray(),
|
||||||
transaction.receipt?.toByteArray(),
|
transaction.receipt?.toByteArray(),
|
||||||
mobileCoinIdentification,
|
mobileCoinIdentification,
|
||||||
chatItem.incoming?.read ?: true
|
chatItem.incoming?.read ?: true,
|
||||||
|
null
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -710,17 +713,17 @@ class ChatItemImportInserter(
|
|||||||
private fun ContentValues.addPaymentNotification(chatItem: ChatItem, chatRecipientId: RecipientId) {
|
private fun ContentValues.addPaymentNotification(chatItem: ChatItem, chatRecipientId: RecipientId) {
|
||||||
val paymentNotification = chatItem.paymentNotification!!
|
val paymentNotification = chatItem.paymentNotification!!
|
||||||
if (chatItem.paymentNotification.amountMob.isNullOrEmpty()) {
|
if (chatItem.paymentNotification.amountMob.isNullOrEmpty()) {
|
||||||
addPaymentTombstoneNoAmount()
|
this.addPaymentTombstoneNoAmount()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val amount = paymentNotification.amountMob?.tryParseMoney() ?: return addPaymentTombstoneNoAmount()
|
val amount = paymentNotification.amountMob?.tryParseMoney() ?: return this.addPaymentTombstoneNoAmount()
|
||||||
val fee = paymentNotification.feeMob?.tryParseMoney() ?: return addPaymentTombstoneNoAmount()
|
val fee = paymentNotification.feeMob?.tryParseMoney() ?: return this.addPaymentTombstoneNoAmount()
|
||||||
|
|
||||||
if (chatItem.paymentNotification.transactionDetails?.failedTransaction != null) {
|
if (chatItem.paymentNotification.transactionDetails?.failedTransaction != null) {
|
||||||
addFailedPaymentNotification(chatItem, amount, fee, chatRecipientId)
|
this.addFailedPaymentNotification(chatItem, amount, fee, chatRecipientId)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
addPaymentTombstoneNoMetadata(chatItem.paymentNotification)
|
this.addPaymentTombstoneNoMetadata(chatItem.paymentNotification)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun PaymentNotification.TransactionDetails.MobileCoinTxoIdentification.toLocal(): PaymentMetaData {
|
private fun PaymentNotification.TransactionDetails.MobileCoinTxoIdentification.toLocal(): PaymentMetaData {
|
||||||
@@ -737,6 +740,7 @@ class ChatItemImportInserter(
|
|||||||
chatRecipientId,
|
chatRecipientId,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
|
0,
|
||||||
chatItem.paymentNotification?.note ?: "",
|
chatItem.paymentNotification?.note ?: "",
|
||||||
if (chatItem.outgoing != null) Direction.SENT else Direction.RECEIVED,
|
if (chatItem.outgoing != null) Direction.SENT else Direction.RECEIVED,
|
||||||
State.FAILED,
|
State.FAILED,
|
||||||
@@ -745,7 +749,8 @@ class ChatItemImportInserter(
|
|||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
chatItem.incoming?.read ?: true
|
chatItem.incoming?.read ?: true,
|
||||||
|
chatItem.paymentNotification?.transactionDetails?.failedTransaction?.reason?.toLocalPaymentFailureReason()
|
||||||
)
|
)
|
||||||
if (uuid != null) {
|
if (uuid != null) {
|
||||||
put(MessageTable.BODY, uuid.toString())
|
put(MessageTable.BODY, uuid.toString())
|
||||||
@@ -755,6 +760,14 @@ class ChatItemImportInserter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun PaymentNotification.TransactionDetails.FailedTransaction.FailureReason.toLocalPaymentFailureReason(): FailureReason {
|
||||||
|
return when (this) {
|
||||||
|
PaymentNotification.TransactionDetails.FailedTransaction.FailureReason.GENERIC -> FailureReason.UNKNOWN
|
||||||
|
PaymentNotification.TransactionDetails.FailedTransaction.FailureReason.NETWORK -> FailureReason.NETWORK
|
||||||
|
PaymentNotification.TransactionDetails.FailedTransaction.FailureReason.INSUFFICIENT_FUNDS -> FailureReason.INSUFFICIENT_FUNDS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun ContentValues.addPaymentTombstoneNoAmount() {
|
private fun ContentValues.addPaymentTombstoneNoAmount() {
|
||||||
put(MessageTable.TYPE, getAsLong(MessageTable.TYPE) or MessageTypes.SPECIAL_TYPE_PAYMENTS_TOMBSTONE)
|
put(MessageTable.TYPE, getAsLong(MessageTable.TYPE) or MessageTypes.SPECIAL_TYPE_PAYMENTS_TOMBSTONE)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -186,6 +186,7 @@ public final class PaymentTable extends DatabaseTable implements RecipientIdData
|
|||||||
public UUID restoreFromBackup(@NonNull RecipientId recipientId,
|
public UUID restoreFromBackup(@NonNull RecipientId recipientId,
|
||||||
long timestamp,
|
long timestamp,
|
||||||
long blockIndex,
|
long blockIndex,
|
||||||
|
long blockTimestamp,
|
||||||
@NonNull String note,
|
@NonNull String note,
|
||||||
@NonNull Direction direction,
|
@NonNull Direction direction,
|
||||||
@NonNull State state,
|
@NonNull State state,
|
||||||
@@ -194,10 +195,16 @@ public final class PaymentTable extends DatabaseTable implements RecipientIdData
|
|||||||
@Nullable byte[] transaction,
|
@Nullable byte[] transaction,
|
||||||
@Nullable byte[] receipt,
|
@Nullable byte[] receipt,
|
||||||
@Nullable PaymentMetaData metaData,
|
@Nullable PaymentMetaData metaData,
|
||||||
boolean seen) {
|
boolean seen,
|
||||||
|
@Nullable FailureReason failureReason)
|
||||||
|
{
|
||||||
UUID uuid = UUID.randomUUID();
|
UUID uuid = UUID.randomUUID();
|
||||||
try {
|
try {
|
||||||
create(uuid, recipientId, null, timestamp, blockIndex, note, direction, state, amount, fee, transaction, receipt, metaData, seen);
|
create(uuid, recipientId, null, timestamp, blockIndex, note, direction, state, amount, fee, transaction, receipt, metaData, seen);
|
||||||
|
updateBlockDetails(uuid, blockIndex, blockTimestamp);
|
||||||
|
if (failureReason != null) {
|
||||||
|
markPaymentFailed(uuid, failureReason);
|
||||||
|
}
|
||||||
} catch (SerializationException | PublicKeyConflictException e) {
|
} catch (SerializationException | PublicKeyConflictException e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -619,13 +626,20 @@ public final class PaymentTable extends DatabaseTable implements RecipientIdData
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static @NonNull PaymentTransaction readPayment(@NonNull Cursor cursor) {
|
private static @NonNull PaymentTransaction readPayment(@NonNull Cursor cursor) {
|
||||||
|
State state = State.deserialize(CursorUtil.requireInt(cursor, STATE));
|
||||||
|
FailureReason failureReason = null;
|
||||||
|
|
||||||
|
if (state == State.FAILED) {
|
||||||
|
failureReason = FailureReason.deserialize(CursorUtil.requireInt(cursor, FAILURE));
|
||||||
|
}
|
||||||
|
|
||||||
return new PaymentTransaction(UUID.fromString(CursorUtil.requireString(cursor, PAYMENT_UUID)),
|
return new PaymentTransaction(UUID.fromString(CursorUtil.requireString(cursor, PAYMENT_UUID)),
|
||||||
getRecipientId(cursor),
|
getRecipientId(cursor),
|
||||||
MobileCoinPublicAddress.fromBase58NullableOrThrow(CursorUtil.requireString(cursor, ADDRESS)),
|
MobileCoinPublicAddress.fromBase58NullableOrThrow(CursorUtil.requireString(cursor, ADDRESS)),
|
||||||
CursorUtil.requireLong(cursor, TIMESTAMP),
|
CursorUtil.requireLong(cursor, TIMESTAMP),
|
||||||
Direction.deserialize(CursorUtil.requireInt(cursor, DIRECTION)),
|
Direction.deserialize(CursorUtil.requireInt(cursor, DIRECTION)),
|
||||||
State.deserialize(CursorUtil.requireInt(cursor, STATE)),
|
state,
|
||||||
FailureReason.deserialize(CursorUtil.requireInt(cursor, FAILURE)),
|
failureReason,
|
||||||
CursorUtil.requireString(cursor, NOTE),
|
CursorUtil.requireString(cursor, NOTE),
|
||||||
getMoneyValue(CursorUtil.requireBlob(cursor, AMOUNT)),
|
getMoneyValue(CursorUtil.requireBlob(cursor, AMOUNT)),
|
||||||
getMoneyValue(CursorUtil.requireBlob(cursor, FEE)),
|
getMoneyValue(CursorUtil.requireBlob(cursor, FEE)),
|
||||||
|
|||||||
Reference in New Issue
Block a user