Simplify sendVerificationStateSyncMessage
This commit is contained in:
parent
0f8f40ee0a
commit
207023272a
@ -46,36 +46,12 @@ final class OutgoingVerificationStateSyncMessage: OutgoingSyncMessage {
|
||||
override class var supportsSecureCoding: Bool { true }
|
||||
|
||||
override func encode(with coder: NSCoder) {
|
||||
super.encode(with: coder)
|
||||
coder.encode(self.identityKey, forKey: "identityKey")
|
||||
coder.encode(NSNumber(value: self.paddingBytesLength), forKey: "paddingBytesLength")
|
||||
coder.encode(self.verificationForRecipientAddress, forKey: "verificationForRecipientAddress")
|
||||
coder.encode(NSNumber(value: self.verificationState.rawValue), forKey: "verificationState")
|
||||
owsFail("Doesn't support serialization.")
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
guard let identityKey = coder.decodeObject(of: NSData.self, forKey: "identityKey") as Data? else {
|
||||
return nil
|
||||
}
|
||||
self.identityKey = identityKey
|
||||
guard let paddingBytesLength = coder.decodeObject(of: NSNumber.self, forKey: "paddingBytesLength") else {
|
||||
return nil
|
||||
}
|
||||
self.paddingBytesLength = paddingBytesLength.uintValue
|
||||
let modernAddress = coder.decodeObject(of: SignalServiceAddress.self, forKey: "verificationForRecipientAddress")
|
||||
self.verificationForRecipientAddress = modernAddress ?? SignalServiceAddress.legacyAddress(
|
||||
serviceIdString: nil,
|
||||
phoneNumber: coder.decodeObject(of: NSString.self, forKey: "verificationForRecipientId") as String?,
|
||||
)
|
||||
owsAssertDebug(self.verificationForRecipientAddress.isValid)
|
||||
guard
|
||||
let rawVerificationState = coder.decodeObject(of: NSNumber.self, forKey: "verificationState"),
|
||||
let verificationState = OWSVerificationState(rawValue: rawVerificationState.uint64Value)
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
self.verificationState = verificationState
|
||||
super.init(coder: coder)
|
||||
// Doesn't support serialization.
|
||||
return nil
|
||||
}
|
||||
|
||||
override var hash: Int {
|
||||
@ -122,24 +98,5 @@ final class OutgoingVerificationStateSyncMessage: OutgoingSyncMessage {
|
||||
return syncMessageBuilder
|
||||
}
|
||||
|
||||
func unpaddedVerifiedLength() -> UInt {
|
||||
guard let verificationForRecipientAci = self.verificationForRecipientAddress.aci else {
|
||||
return 0
|
||||
}
|
||||
|
||||
let verifiedProto = OWSRecipientIdentity.buildVerifiedProto(
|
||||
destinationAci: verificationForRecipientAci,
|
||||
identityKey: self.identityKey,
|
||||
verificationState: self.verificationState,
|
||||
paddingBytesLength: 0,
|
||||
)
|
||||
do {
|
||||
return UInt(try verifiedProto.serializedData().count)
|
||||
} catch {
|
||||
owsFailDebug("could not serialize protobuf.")
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
override var isUrgent: Bool { false }
|
||||
}
|
||||
|
||||
@ -686,55 +686,22 @@ public class OWSIdentityManagerImpl: OWSIdentityManager {
|
||||
}
|
||||
|
||||
private func sendVerificationStateSyncMessage(for recipientUniqueId: RecipientUniqueId, message: OutgoingVerificationStateSyncMessage) {
|
||||
let address = message.verificationForRecipientAddress
|
||||
let contactThread = TSContactThread.getOrCreateThread(contactAddress: address)
|
||||
|
||||
// DURABLE CLEANUP - we could replace the custom durability logic in this
|
||||
// class with a durable JobQueue.
|
||||
let nullMessagePromise = db.write { tx in
|
||||
// Send null message to appear as though we're sending a normal message to
|
||||
// cover the sync message sent subsequently
|
||||
let nullMessage = OutgoingNullMessage(
|
||||
contactThread: contactThread,
|
||||
verificationStateSyncMessage: message,
|
||||
tx: tx,
|
||||
)
|
||||
let syncMessagePromise = self.db.write { tx in
|
||||
let preparedMessage = PreparedOutgoingMessage.preprepared(
|
||||
transientMessageWithoutAttachments: nullMessage,
|
||||
transientMessageWithoutAttachments: message,
|
||||
)
|
||||
return messageSenderJobQueue.add(
|
||||
return self.messageSenderJobQueue.add(
|
||||
.promise,
|
||||
message: preparedMessage,
|
||||
limitToCurrentProcessLifetime: true,
|
||||
transaction: tx,
|
||||
)
|
||||
}
|
||||
|
||||
nullMessagePromise.done(on: DispatchQueue.global()) {
|
||||
Logger.info("Successfully sent verification state NullMessage")
|
||||
let syncMessagePromise = self.db.write { tx in
|
||||
let preparedMessage = PreparedOutgoingMessage.preprepared(
|
||||
transientMessageWithoutAttachments: message,
|
||||
)
|
||||
return self.messageSenderJobQueue.add(
|
||||
.promise,
|
||||
message: preparedMessage,
|
||||
limitToCurrentProcessLifetime: true,
|
||||
transaction: tx,
|
||||
)
|
||||
}
|
||||
syncMessagePromise.done(on: DispatchQueue.global()) {
|
||||
Logger.info("Successfully sent verification state sync message")
|
||||
self.db.write { tx in self.clearSyncMessage(for: recipientUniqueId, tx: tx) }
|
||||
}.catch(on: DispatchQueue.global()) { error in
|
||||
Logger.error("Failed to send verification state sync message: \(error)")
|
||||
}
|
||||
syncMessagePromise.done(on: DispatchQueue.global()) {
|
||||
Logger.info("Successfully sent verification state sync message")
|
||||
self.db.write { tx in self.clearSyncMessage(for: recipientUniqueId, tx: tx) }
|
||||
}.catch(on: DispatchQueue.global()) { error in
|
||||
Logger.error("Failed to send verification state NullMessage: \(error)")
|
||||
if error is MessageSenderNoSuchSignalRecipientError {
|
||||
Logger.info("Removing retries for syncing verification for unregistered user: \(address)")
|
||||
self.db.write { tx in self.clearSyncMessage(for: recipientUniqueId, tx: tx) }
|
||||
}
|
||||
Logger.error("Failed to send verification state sync message: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -8,10 +8,7 @@ import Foundation
|
||||
@objc(OWSOutgoingNullMessage)
|
||||
final class OutgoingNullMessage: TransientOutgoingMessage {
|
||||
|
||||
let verificationStateSyncMessage: OutgoingVerificationStateSyncMessage?
|
||||
|
||||
init(contactThread: TSContactThread, verificationStateSyncMessage: OutgoingVerificationStateSyncMessage? = nil, tx: DBReadTransaction) {
|
||||
self.verificationStateSyncMessage = verificationStateSyncMessage
|
||||
init(contactThread: TSContactThread, tx: DBReadTransaction) {
|
||||
let messageBuilder = TSOutgoingMessageBuilder.outgoingMessageBuilder(thread: contactThread)
|
||||
super.init(
|
||||
outgoingMessageWith: messageBuilder,
|
||||
@ -24,59 +21,13 @@ final class OutgoingNullMessage: TransientOutgoingMessage {
|
||||
|
||||
override class var supportsSecureCoding: Bool { true }
|
||||
|
||||
override func encode(with coder: NSCoder) {
|
||||
super.encode(with: coder)
|
||||
if let verificationStateSyncMessage {
|
||||
coder.encode(verificationStateSyncMessage, forKey: "verificationStateSyncMessage")
|
||||
}
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
self.verificationStateSyncMessage = coder.decodeObject(of: OutgoingVerificationStateSyncMessage.self, forKey: "verificationStateSyncMessage")
|
||||
super.init(coder: coder)
|
||||
}
|
||||
|
||||
override var hash: Int {
|
||||
var hasher = Hasher()
|
||||
hasher.combine(super.hash)
|
||||
hasher.combine(self.verificationStateSyncMessage)
|
||||
return hasher.finalize()
|
||||
}
|
||||
|
||||
override func isEqual(_ object: Any?) -> Bool {
|
||||
guard let object = object as? Self else { return false }
|
||||
guard super.isEqual(object) else { return false }
|
||||
guard self.verificationStateSyncMessage == object.verificationStateSyncMessage else { return false }
|
||||
return true
|
||||
}
|
||||
|
||||
override func contentBuilder(thread: TSThread, transaction: DBReadTransaction) -> SSKProtoContentBuilder? {
|
||||
let nullMessageBuilder = SSKProtoNullMessage.builder()
|
||||
|
||||
if let verificationStateSyncMessage {
|
||||
var contentLength = verificationStateSyncMessage.unpaddedVerifiedLength()
|
||||
|
||||
owsAssertDebug(verificationStateSyncMessage.paddingBytesLength > 0)
|
||||
|
||||
// We add the same amount of padding in the VerificationStateSync message
|
||||
// and its corresponding NullMessage so that the sync message is
|
||||
// indistinguishable from an outgoing Sent transcript corresponding to the
|
||||
// NullMessage. We pad the NullMessage so as to obscure its content. The
|
||||
// sync message (like all sync messages) will be *additionally* padded by
|
||||
// the superclass while being sent. The end result is we send a NullMessage
|
||||
// of a non-distinct size, and a verification sync which is ~1-512 bytes
|
||||
// larger than that.
|
||||
contentLength += verificationStateSyncMessage.paddingBytesLength
|
||||
|
||||
owsAssertDebug(contentLength > 0)
|
||||
|
||||
nullMessageBuilder.setPadding(Randomness.generateRandomBytes(contentLength))
|
||||
}
|
||||
|
||||
let nullMessage = nullMessageBuilder.buildInfallibly()
|
||||
|
||||
let contentBuilder = SSKProtoContent.builder()
|
||||
contentBuilder.setNullMessage(nullMessage)
|
||||
contentBuilder.setNullMessage(SSKProtoNullMessage.builder().buildInfallibly())
|
||||
return contentBuilder
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user