Skip redundant identity key storage service update

This commit is contained in:
Max Radermacher 2026-05-06 15:15:48 -05:00 committed by GitHub
parent 3394d45e54
commit d9d762062f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 75 additions and 21 deletions

View File

@ -56,7 +56,7 @@ class DebugUISessionState: DebugUIPage {
flippedKey[i] = currentKey[i] ^ 0xFF
}
owsAssertDebug(flippedKey.count == currentKey.count)
identityManager.saveIdentityKey(flippedKey, for: serviceId, tx: tx)
identityManager.saveIdentityKey(flippedKey, for: serviceId, shouldUpdateStorageService: true, tx: tx)
}
}
}

View File

@ -259,7 +259,7 @@ public class MessageSender {
transaction tx: DBWriteTransaction,
) {
let identityManager = DependenciesBridge.shared.identityManager
identityManager.saveIdentityKey(identityKey, for: serviceId, tx: tx)
identityManager.saveIdentityKey(identityKey, for: serviceId, shouldUpdateStorageService: true, tx: tx)
}
/// If true, we expect fetching a bundle will fail no matter what it contains.

View File

@ -82,7 +82,7 @@ open class MockIdentityManager: OWSIdentityManager {
}
open func identityKey(for address: SignalServiceAddress, tx: DBReadTransaction) -> Data? { fatalError() }
open func saveIdentityKey(_ identityKey: Data, for serviceId: ServiceId, tx: DBWriteTransaction) -> Result<IdentityChange, RecipientIdError> { fatalError() }
open func saveIdentityKey(_ identityKey: Data, for serviceId: ServiceId, shouldUpdateStorageService: Bool, tx: DBWriteTransaction) -> Result<IdentityChange, RecipientIdError> { fatalError() }
open func untrustedIdentityForSending(to address: SignalServiceAddress, untrustedThreshold: Date?, tx: DBReadTransaction) -> OWSRecipientIdentity? { fatalError() }
open func tryToSyncQueuedVerificationStates() { fatalError() }
open func verificationState(for address: SignalServiceAddress, tx: DBReadTransaction) -> VerificationState { fatalError() }

View File

@ -33,7 +33,12 @@ public protocol OWSIdentityManager {
func identityKey(for serviceId: ServiceId, tx: DBReadTransaction) throws -> IdentityKey?
@discardableResult
func saveIdentityKey(_ identityKey: Data, for serviceId: ServiceId, tx: DBWriteTransaction) -> Result<IdentityChange, RecipientIdError>
func saveIdentityKey(
_ identityKey: Data,
for serviceId: ServiceId,
shouldUpdateStorageService: Bool,
tx: DBWriteTransaction,
) -> Result<IdentityChange, RecipientIdError>
func insertIdentityChangeInfoMessage(for serviceId: ServiceId, wasIdentityVerified: Bool, tx: DBWriteTransaction)
func insertSessionSwitchoverEvent(for recipient: SignalRecipient, phoneNumber: String?, tx: DBWriteTransaction)
@ -68,8 +73,18 @@ public protocol OWSIdentityManager {
extension OWSIdentityManager {
@discardableResult
public func saveIdentityKey(_ identityKey: IdentityKey, for serviceId: ServiceId, tx: DBWriteTransaction) -> Result<IdentityChange, RecipientIdError> {
return saveIdentityKey(identityKey.publicKey.keyBytes, for: serviceId, tx: tx)
public func saveIdentityKey(
_ identityKey: IdentityKey,
for serviceId: ServiceId,
shouldUpdateStorageService: Bool,
tx: DBWriteTransaction,
) -> Result<IdentityChange, RecipientIdError> {
return saveIdentityKey(
identityKey.publicKey.keyBytes,
for: serviceId,
shouldUpdateStorageService: shouldUpdateStorageService,
tx: tx,
)
}
}
@ -137,6 +152,7 @@ public class IdentityStore: IdentityKeyStore {
try identityManager.saveIdentityKey(
identityKey,
for: address.serviceId,
shouldUpdateStorageService: true,
tx: context.asTransaction,
).get()
}
@ -350,12 +366,31 @@ public class OWSIdentityManagerImpl: OWSIdentityManager {
}
@discardableResult
public func saveIdentityKey(_ identityKey: Data, for serviceId: ServiceId, tx: DBWriteTransaction) -> Result<IdentityChange, RecipientIdError> {
public func saveIdentityKey(
_ identityKey: Data,
for serviceId: ServiceId,
shouldUpdateStorageService: Bool,
tx: DBWriteTransaction,
) -> Result<IdentityChange, RecipientIdError> {
let recipientResult = recipientIdFinder.ensureRecipient(for: serviceId, tx: tx)
return recipientResult.map({ _saveIdentityKey(identityKey, for: serviceId, recipient: $0, tx: tx) })
return recipientResult.map({
return _saveIdentityKey(
identityKey,
for: serviceId,
recipient: $0,
shouldUpdateStorageService: shouldUpdateStorageService,
tx: tx,
)
})
}
private func _saveIdentityKey(_ identityKey: Data, for serviceId: ServiceId, recipient: SignalRecipient, tx: DBWriteTransaction) -> IdentityChange {
private func _saveIdentityKey(
_ identityKey: Data,
for serviceId: ServiceId,
recipient: SignalRecipient,
shouldUpdateStorageService: Bool,
tx: DBWriteTransaction,
) -> IdentityChange {
owsAssertDebug(identityKey.count == Constants.storedIdentityKeyLength)
let existingIdentity = OWSRecipientIdentity.anyFetch(uniqueId: recipient.uniqueId, transaction: tx)
@ -371,7 +406,9 @@ public class OWSIdentityManagerImpl: OWSIdentityManager {
// Cancel any pending verification state sync messages for this recipient.
clearSyncMessage(for: recipient.uniqueId, tx: tx)
fireIdentityStateChangeNotification(after: tx)
storageServiceManager.recordPendingUpdates(updatedRecipientUniqueIds: [recipient.uniqueId])
if shouldUpdateStorageService {
storageServiceManager.recordPendingUpdates(updatedRecipientUniqueIds: [recipient.uniqueId])
}
return .newOrUnchanged
}
@ -398,7 +435,9 @@ public class OWSIdentityManagerImpl: OWSIdentityManager {
sessionStore.archiveSessions(forRecipientId: recipient.id, localIdentity: .aci, tx: tx)
// Cancel any pending verification state sync messages for this recipient.
clearSyncMessage(for: recipient.uniqueId, tx: tx)
storageServiceManager.recordPendingUpdates(updatedRecipientUniqueIds: [recipient.uniqueId])
if shouldUpdateStorageService {
storageServiceManager.recordPendingUpdates(updatedRecipientUniqueIds: [recipient.uniqueId])
}
return .replacedExisting
}
@ -871,7 +910,7 @@ public class OWSIdentityManagerImpl: OWSIdentityManager {
if shouldSaveIdentityKey {
// Ensure a remote identity exists for this key. We may be learning about
// it for the first time.
saveIdentityKey(identityKey, for: aci, tx: tx)
saveIdentityKey(identityKey, for: aci, shouldUpdateStorageService: false, tx: tx)
recipientIdentity = OWSRecipientIdentity.anyFetch(uniqueId: recipientUniqueId, transaction: tx)
}
@ -1018,7 +1057,7 @@ public class OWSIdentityManagerImpl: OWSIdentityManager {
continue
}
self.saveIdentityKey(identityKey, for: serviceId, tx: tx)
self.saveIdentityKey(identityKey, for: serviceId, shouldUpdateStorageService: true, tx: tx)
}
}
}

View File

@ -484,7 +484,7 @@ public class ProfileFetcherJob {
}
let identityManager = DependenciesBridge.shared.identityManager
identityManager.saveIdentityKey(profile.identityKey, for: serviceId, tx: transaction)
identityManager.saveIdentityKey(profile.identityKey, for: serviceId, shouldUpdateStorageService: true, tx: transaction)
let paymentAddress = fetchedProfile.decryptedProfile?.paymentAddress(identityKey: fetchedProfile.identityKey)
self.paymentsHelper.setArePaymentsEnabled(

View File

@ -563,7 +563,12 @@ class StorageServiceContactRecordUpdater: StorageServiceRecordUpdater {
let localIdentityKey = try? identityManager.identityKey(for: serviceIds.aciOrElsePni, tx: tx)
if let identityKey = record.identityKey.flatMap({ try? IdentityKey(bytes: $0) }) {
if identityKey != localIdentityKey {
identityManager.saveIdentityKey(identityKey, for: serviceIds.aciOrElsePni, tx: tx)
identityManager.saveIdentityKey(
identityKey,
for: serviceIds.aciOrElsePni,
shouldUpdateStorageService: false,
tx: tx,
)
}
// Make sure we fetch this after changing the identity key.
let identityState = record.identityState.verificationState

View File

@ -51,7 +51,7 @@ class OWSRecipientIdentityTest: SSKBaseTest {
for serviceId in recipients {
var recipient = recipientFetcher.fetchOrCreate(serviceId: serviceId, tx: tx)
recipientManager.markAsRegisteredAndSave(&recipient, shouldUpdateStorageService: false, tx: tx)
identityManager.saveIdentityKey(identityKey(serviceId), for: serviceId, tx: tx)
identityManager.saveIdentityKey(identityKey(serviceId), for: serviceId, shouldUpdateStorageService: false, tx: tx)
}
// Create a group with our recipients plus us.

View File

@ -31,7 +31,7 @@ class TSContactThreadTest: SSKBaseTest {
let identityManager = DependenciesBridge.shared.identityManager
SSKEnvironment.shared.databaseStorageRef.write { tx in
_ = identityManager.saveIdentityKey(Data(count: 32), for: contactThread.contactAddress.serviceId!, tx: tx)
_ = identityManager.saveIdentityKey(Data(count: 32), for: contactThread.contactAddress.serviceId!, shouldUpdateStorageService: false, tx: tx)
}
XCTAssert(contactThread.hasSafetyNumbers())

View File

@ -45,7 +45,7 @@ class OWSIdentityManagerTests: SSKBaseTest {
let newKey = IdentityKeyPair.generate().identityKey
let aci = Aci.randomForTesting()
try write { transaction in
identityManager.saveIdentityKey(newKey, for: aci, tx: transaction)
identityManager.saveIdentityKey(newKey, for: aci, shouldUpdateStorageService: false, tx: transaction)
XCTAssert(try identityManager.isTrustedIdentityKey(
newKey,
serviceId: aci,
@ -65,7 +65,7 @@ class OWSIdentityManagerTests: SSKBaseTest {
let originalKey = IdentityKeyPair.generate().identityKey
let aci = Aci.randomForTesting()
try write { transaction in
identityManager.saveIdentityKey(originalKey, for: aci, tx: transaction)
identityManager.saveIdentityKey(originalKey, for: aci, shouldUpdateStorageService: false, tx: transaction)
XCTAssert(try identityManager.isTrustedIdentityKey(
originalKey,

View File

@ -163,7 +163,12 @@ class FingerprintScanViewController: OWSViewController, OWSNavigationChildContro
handler: { _ in
DependenciesBridge.shared.db.write { tx in
let identityManager = DependenciesBridge.shared.identityManager
identityManager.saveIdentityKey(identityKey, for: recipientAci, tx: tx)
identityManager.saveIdentityKey(
identityKey,
for: recipientAci,
shouldUpdateStorageService: true,
tx: tx,
)
_ = identityManager.setVerificationState(
.verified,
of: identityKey.publicKey.keyBytes,

View File

@ -715,7 +715,12 @@ public class FingerprintViewController: OWSViewController, OWSNavigationChildCon
newVerificationState = .verified
}
deps.identityManager.saveIdentityKey(identityKey, for: recipientAci, tx: tx)
deps.identityManager.saveIdentityKey(
identityKey,
for: recipientAci,
shouldUpdateStorageService: true,
tx: tx,
)
_ = deps.identityManager.setVerificationState(
newVerificationState,
of: identityKey.publicKey.keyBytes,