Fix payment notification backup import/export.

This commit is contained in:
Greyson Parrelli
2024-09-22 15:09:04 -04:00
parent a76f5e600e
commit ecd16dbe9c
3 changed files with 46 additions and 17 deletions

View File

@@ -503,7 +503,7 @@ class ChatItemExportIterator(private val cursor: Cursor, private val batchSize:
PaymentNotification(
amountMob = payment.amount.serializeAmountString(),
feeMob = payment.fee.serializeAmountString(),
note = payment.note,
note = payment.note.takeUnless { it.isEmpty() },
transactionDetails = payment.getTransactionDetails()
)
}
@@ -789,16 +789,18 @@ class ChatItemExportIterator(private val cursor: Cursor, private val batchSize:
}
private fun PaymentTable.PaymentTransaction.getTransactionDetails(): PaymentNotification.TransactionDetails? {
if (failureReason != null || state == State.FAILED) {
return PaymentNotification.TransactionDetails(failedTransaction = PaymentNotification.TransactionDetails.FailedTransaction(reason = failureReason.toBackupFailureReason()))
if (this.failureReason != null || this.state == State.FAILED) {
return PaymentNotification.TransactionDetails(failedTransaction = PaymentNotification.TransactionDetails.FailedTransaction(reason = this.failureReason.toBackupFailureReason()))
}
return PaymentNotification.TransactionDetails(
transaction = PaymentNotification.TransactionDetails.Transaction(
status = this.state.toBackupState(),
timestamp = timestamp,
blockIndex = blockIndex,
blockTimestamp = blockTimestamp,
mobileCoinIdentification = paymentMetaData.mobileCoinTxoIdentification?.toBackup()
timestamp = this.timestamp,
blockIndex = this.blockIndex,
blockTimestamp = this.blockTimestamp,
mobileCoinIdentification = this.paymentMetaData.mobileCoinTxoIdentification?.toBackup(),
transaction = this.transaction?.toByteString(),
receipt = this.receipt?.toByteString()
)
)
}

View File

@@ -62,6 +62,7 @@ import org.thoughtcrime.securesms.database.model.databaseprotos.ThreadMergeEvent
import org.thoughtcrime.securesms.mms.QuoteModel
import org.thoughtcrime.securesms.payments.CryptoValueUtil
import org.thoughtcrime.securesms.payments.Direction
import org.thoughtcrime.securesms.payments.FailureReason
import org.thoughtcrime.securesms.payments.State
import org.thoughtcrime.securesms.payments.proto.PaymentMetaData
import org.thoughtcrime.securesms.profiles.ProfileName
@@ -494,6 +495,7 @@ class ChatItemImportInserter(
chatRecipientId,
transaction.timestamp ?: 0,
transaction.blockIndex ?: 0,
transaction.blockTimestamp ?: 0,
paymentNotification.note ?: "",
if (chatItem.outgoing != null) Direction.SENT else Direction.RECEIVED,
transaction.status.toLocalStatus(),
@@ -502,7 +504,8 @@ class ChatItemImportInserter(
transaction.transaction?.toByteArray(),
transaction.receipt?.toByteArray(),
mobileCoinIdentification,
chatItem.incoming?.read ?: true
chatItem.incoming?.read ?: true,
null
)
}
@@ -710,17 +713,17 @@ class ChatItemImportInserter(
private fun ContentValues.addPaymentNotification(chatItem: ChatItem, chatRecipientId: RecipientId) {
val paymentNotification = chatItem.paymentNotification!!
if (chatItem.paymentNotification.amountMob.isNullOrEmpty()) {
addPaymentTombstoneNoAmount()
this.addPaymentTombstoneNoAmount()
return
}
val amount = paymentNotification.amountMob?.tryParseMoney() ?: return addPaymentTombstoneNoAmount()
val fee = paymentNotification.feeMob?.tryParseMoney() ?: return addPaymentTombstoneNoAmount()
val amount = paymentNotification.amountMob?.tryParseMoney() ?: return this.addPaymentTombstoneNoAmount()
val fee = paymentNotification.feeMob?.tryParseMoney() ?: return this.addPaymentTombstoneNoAmount()
if (chatItem.paymentNotification.transactionDetails?.failedTransaction != null) {
addFailedPaymentNotification(chatItem, amount, fee, chatRecipientId)
this.addFailedPaymentNotification(chatItem, amount, fee, chatRecipientId)
return
}
addPaymentTombstoneNoMetadata(chatItem.paymentNotification)
this.addPaymentTombstoneNoMetadata(chatItem.paymentNotification)
}
private fun PaymentNotification.TransactionDetails.MobileCoinTxoIdentification.toLocal(): PaymentMetaData {
@@ -737,6 +740,7 @@ class ChatItemImportInserter(
chatRecipientId,
0,
0,
0,
chatItem.paymentNotification?.note ?: "",
if (chatItem.outgoing != null) Direction.SENT else Direction.RECEIVED,
State.FAILED,
@@ -745,7 +749,8 @@ class ChatItemImportInserter(
null,
null,
null,
chatItem.incoming?.read ?: true
chatItem.incoming?.read ?: true,
chatItem.paymentNotification?.transactionDetails?.failedTransaction?.reason?.toLocalPaymentFailureReason()
)
if (uuid != null) {
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() {
put(MessageTable.TYPE, getAsLong(MessageTable.TYPE) or MessageTypes.SPECIAL_TYPE_PAYMENTS_TOMBSTONE)
}

View File

@@ -186,6 +186,7 @@ public final class PaymentTable extends DatabaseTable implements RecipientIdData
public UUID restoreFromBackup(@NonNull RecipientId recipientId,
long timestamp,
long blockIndex,
long blockTimestamp,
@NonNull String note,
@NonNull Direction direction,
@NonNull State state,
@@ -194,10 +195,16 @@ public final class PaymentTable extends DatabaseTable implements RecipientIdData
@Nullable byte[] transaction,
@Nullable byte[] receipt,
@Nullable PaymentMetaData metaData,
boolean seen) {
boolean seen,
@Nullable FailureReason failureReason)
{
UUID uuid = UUID.randomUUID();
try {
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) {
return null;
}
@@ -619,13 +626,20 @@ public final class PaymentTable extends DatabaseTable implements RecipientIdData
}
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)),
getRecipientId(cursor),
MobileCoinPublicAddress.fromBase58NullableOrThrow(CursorUtil.requireString(cursor, ADDRESS)),
CursorUtil.requireLong(cursor, TIMESTAMP),
Direction.deserialize(CursorUtil.requireInt(cursor, DIRECTION)),
State.deserialize(CursorUtil.requireInt(cursor, STATE)),
FailureReason.deserialize(CursorUtil.requireInt(cursor, FAILURE)),
state,
failureReason,
CursorUtil.requireString(cursor, NOTE),
getMoneyValue(CursorUtil.requireBlob(cursor, AMOUNT)),
getMoneyValue(CursorUtil.requireBlob(cursor, FEE)),