Updated on 2026-08-14
This commit is contained in:
commit
4fc52e2052
4 changed files with 15 additions and 19 deletions
|
|
@ -126,9 +126,8 @@ internal class DefaultAddressBookRepository(
|
|||
|
||||
override suspend fun syncAddressBooks(): Either<AddressBookSyncError, Unit> = withContext(dispatchers.default) {
|
||||
val wallets = userWalletsListRepository.userWalletsSync()
|
||||
// Debug (Logcat only, dev builds) — the persisted prod log stays quiet on the happy path; only failures
|
||||
// below are written at Error level.
|
||||
logger.d("Syncing address books for ${wallets.size} wallet(s)")
|
||||
// Metadata only (wallet count) — persisted to the prod log so sync activity is traceable.
|
||||
logger.i("Syncing address books for ${wallets.size} wallet(s)")
|
||||
// The backend rejects more than MAX_SYNC_WALLETS per request, so sync in chunks and stop on the
|
||||
// first failed chunk.
|
||||
wallets.chunked(MAX_SYNC_WALLETS)
|
||||
|
|
@ -150,13 +149,13 @@ internal class DefaultAddressBookRepository(
|
|||
call = {
|
||||
val response = withContext(dispatchers.io) { addressBookApi.syncAddressBooks(request).bind() }
|
||||
// Only wallets whose etag changed are returned; the rest keep their local copy.
|
||||
logger.d("Sync response: ${response.items.size} updated book(s) out of ${wallets.size} requested")
|
||||
logger.i("Sync response: ${response.items.size} updated book(s) out of ${wallets.size} requested")
|
||||
response.items.forEach { item ->
|
||||
val userWalletId = UserWalletId(stringValue = item.walletId)
|
||||
// Metadata only — helps QA verify what the backend delivered (esp. for cross-platform books).
|
||||
// Debug (Logcat only) to keep the persisted prod log free of happy-path sync noise.
|
||||
logger.d(
|
||||
"Storing synced address book for wallet ${item.walletId}: version=${item.version}, " +
|
||||
// Metadata only (no keys/ciphertext/plaintext) — helps QA verify what the backend delivered
|
||||
// (esp. for cross-platform books).
|
||||
logger.i(
|
||||
"Storing synced address book for wallet ${item.walletId}: " +
|
||||
"updatedAt=${item.updatedAt}, nonceLen=${item.nonce.length}, " +
|
||||
"ciphertextLen=${item.ciphertext.length}, authTagLen=${item.authTag.length}",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -62,9 +62,9 @@ class AddressBookCipher {
|
|||
authTag = authTag.toHexString().lowercase(),
|
||||
).also { blob ->
|
||||
// Metadata only — the plaintext (contact names/addresses/memos) is never logged.
|
||||
logger.d(
|
||||
logger.i(
|
||||
"Encrypted address book for wallet ${blob.walletId}: contacts=${addressBook.contacts.size}, " +
|
||||
"plaintextBytes=${plaintext.size}, version=${blob.version}, " +
|
||||
"plaintextBytes=${plaintext.size}, " +
|
||||
"nonceLen=${blob.nonce.length}, ciphertextLen=${blob.ciphertext.length}, " +
|
||||
"authTagLen=${blob.authTag.length}",
|
||||
)
|
||||
|
|
@ -73,14 +73,14 @@ class AddressBookCipher {
|
|||
|
||||
fun decrypt(blob: AddressBookBlob, userWallet: UserWallet): Either<AddressBookCryptoError, AddressBook> = either {
|
||||
// Metadata only — helps QA correlate a failing blob with what was received from the backend/other platform.
|
||||
logger.d(
|
||||
"Decrypting address book for wallet ${blob.walletId}: version=${blob.version}, " +
|
||||
logger.i(
|
||||
"Decrypting address book for wallet ${blob.walletId}: " +
|
||||
"updatedAt=${blob.updatedAt}, nonceLen=${blob.nonce.length}, " +
|
||||
"ciphertextLen=${blob.ciphertext.length}, authTagLen=${blob.authTag.length}",
|
||||
)
|
||||
|
||||
ensure(blob.walletId == userWallet.walletId.stringValue) {
|
||||
logger.w(
|
||||
logger.e(
|
||||
"Wallet mismatch decrypting address book: blob wallet=${blob.walletId}, " +
|
||||
"target wallet=${userWallet.walletId.stringValue}",
|
||||
)
|
||||
|
|
@ -116,12 +116,12 @@ class AddressBookCipher {
|
|||
// reason (missing/extra field, wrong type, JSON path) but strips any raw plaintext the exception echoes.
|
||||
logger.e(
|
||||
"Failed to parse decrypted address book for wallet ${blob.walletId} " +
|
||||
"(plaintextBytes=${plaintext.size}, version=${blob.version}): ${error.safeDescription()}. " +
|
||||
"(plaintextBytes=${plaintext.size}): ${error.safeDescription()}. " +
|
||||
"Decryption OK → cross-platform payload schema/format mismatch.",
|
||||
)
|
||||
raise(AddressBookCryptoError.MalformedBlob)
|
||||
}.also { addressBook ->
|
||||
logger.d(
|
||||
logger.i(
|
||||
messageString = "Decrypted address book for wallet ${blob.walletId}: " +
|
||||
"contacts=${addressBook.contacts.size}",
|
||||
)
|
||||
|
|
@ -135,7 +135,7 @@ class AddressBookCipher {
|
|||
): Nothing {
|
||||
logger.e(
|
||||
"Address book blob has non-hex $field for wallet ${blob.walletId} " +
|
||||
"(${field}Len=${value.length}, version=${blob.version}).",
|
||||
"(${field}Len=${value.length}).",
|
||||
)
|
||||
raise(AddressBookCryptoError.DecryptionFailed)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,7 +112,6 @@ internal class ContactsBlockModelTest {
|
|||
id = AddressEntryId("e-$id"),
|
||||
address = "0x$id",
|
||||
networkId = Network.RawID(ETHEREUM),
|
||||
networkName = "Ethereum",
|
||||
memo = null,
|
||||
signature = "sig",
|
||||
),
|
||||
|
|
|
|||
|
|
@ -986,7 +986,6 @@ internal class EditContactModelTest {
|
|||
id = AddressEntryId("e-1"),
|
||||
address = "0xAAA",
|
||||
networkId = Network.RawID("ethereum"),
|
||||
networkName = "Ethereum",
|
||||
memo = null,
|
||||
signature = "sig",
|
||||
),
|
||||
|
|
@ -994,7 +993,6 @@ internal class EditContactModelTest {
|
|||
id = AddressEntryId("e-2"),
|
||||
address = "0xBBB",
|
||||
networkId = Network.RawID("bsc"),
|
||||
networkName = "BSC",
|
||||
memo = null,
|
||||
signature = "sig",
|
||||
),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue