From 2d16b98ebbb5b53361fc665898c8acd81c348bdf Mon Sep 17 00:00:00 2001 From: SeniorZhai Date: Wed, 30 Sep 2026 14:32:40 +0800 Subject: [PATCH] fix(web3): scope transaction status updates by address --- .../android/db/web3/Web3TransactionDao.kt | 4 +-- .../android/repository/TokenRepository.kt | 4 +-- .../TokenRepositoryWalletTransactionTest.kt | 33 +++++++++++++++++++ 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/one/mixin/android/db/web3/Web3TransactionDao.kt b/app/src/main/java/one/mixin/android/db/web3/Web3TransactionDao.kt index 8d144a499f..f4c6edbc5a 100644 --- a/app/src/main/java/one/mixin/android/db/web3/Web3TransactionDao.kt +++ b/app/src/main/java/one/mixin/android/db/web3/Web3TransactionDao.kt @@ -64,8 +64,8 @@ interface Web3TransactionDao : BaseDao { @Query("DELETE FROM transactions WHERE status = 'pending' AND transaction_hash = :hash AND chain_id = :chainId") fun deletePending(hash: String, chainId: String) - @Query("UPDATE transactions SET status = :status WHERE transaction_hash = :hash AND chain_id = :chainId") - fun updateTransaction(hash: String, status: String, chainId: String) + @Query("UPDATE transactions SET status = :status WHERE transaction_hash = :hash AND chain_id = :chainId AND address = :address") + fun updateTransaction(hash: String, status: String, chainId: String, address: String) @Query("DELETE FROM transactions") suspend fun deleteAllTransactions() diff --git a/app/src/main/java/one/mixin/android/repository/TokenRepository.kt b/app/src/main/java/one/mixin/android/repository/TokenRepository.kt index d3af331ddf..7ceeb861e0 100644 --- a/app/src/main/java/one/mixin/android/repository/TokenRepository.kt +++ b/app/src/main/java/one/mixin/android/repository/TokenRepository.kt @@ -1897,7 +1897,7 @@ class TokenRepository updatedAt = updatedAt, ), ) - web3TransactionDao.updateTransaction(hash, status, chainId) + web3TransactionDao.updateTransaction(hash, status, chainId, pendingRaw.account) } } @@ -1910,7 +1910,7 @@ class TokenRepository ) { walletDatabase.withRoomTransaction { web3RawTransactionDao.insertSuspend(raw) - web3TransactionDao.updateTransaction(hash, status, chainId) + web3TransactionDao.updateTransaction(hash, status, chainId, raw.account) if (chainId !in Constants.Web3UtxoChainIds || utxoRawTransactionHexToDeleteOutputs.isNullOrBlank()) return@withRoomTransaction val cleanedHex: String = utxoRawTransactionHexToDeleteOutputs.removePrefix("0x").trim() if (cleanedHex.isBlank()) return@withRoomTransaction diff --git a/app/src/test/java/one/mixin/android/repository/TokenRepositoryWalletTransactionTest.kt b/app/src/test/java/one/mixin/android/repository/TokenRepositoryWalletTransactionTest.kt index 24b34c7c95..2c5e505fac 100644 --- a/app/src/test/java/one/mixin/android/repository/TokenRepositoryWalletTransactionTest.kt +++ b/app/src/test/java/one/mixin/android/repository/TokenRepositoryWalletTransactionTest.kt @@ -198,6 +198,39 @@ class TokenRepositoryWalletTransactionTest { } } + @Test + fun statusUpdatesOnlyAffectMatchingTransactionAddress() = runBlocking { + insertSigned() + wallet.web3AddressDao().insertSuspend(Web3Address("receiver-address", "receiver-wallet", chain, "receiver", null, createdAt)) + val outgoing = assertNotNull(transaction("signed")) + val records = listOf( + outgoing, + outgoing.copy(address = "receiver", transactionType = "transfer_in"), + outgoing.copy(chainId = "other-chain"), + outgoing.copy(transactionHash = "other-hash"), + ) + for (gasless in listOf(true, false)) { + wallet.web3TransactionDao().insert(*records.toTypedArray()) + val status = if (gasless) "failed" else "success" + if (gasless) { + repository.updateGaslessPendingTransactionStatus("wallet", "signed", chain, status, updatedAt) + } else { + repository.insertRawTransactionAndUpdateTransactionStatus(rawRecord("signed").copy(state = status), "signed", status, chain, null) + } + assertEquals(status, assertNotNull(raw("signed")).state) + for (record in records) { + RoomDatabaseCompat.query( + wallet, + "SELECT status FROM transactions WHERE transaction_hash = ? AND chain_id = ? AND address = ?", + arrayOf(record.transactionHash, record.chainId, record.address), + ).use { + assertTrue(it.moveToFirst()) + assertEquals(if (record == outgoing) status else "pending", it.getString(0)) + } + } + } + } + @Test fun statusUpdateWithoutTransactionStillUpdatesRawRow() = runBlocking { wallet.web3RawTransactionDao().insertSuspend(rawRecord("signed"))