@@ -473,11 +473,9 @@ class MessageDecryptDeduplicationRecord: Codable, FetchableRecord, PersistableRe
473473 static let databaseTableName = " MessageDecryptDeduplication "
474474
475475 var id : Int64 ?
476- let serviceTimestamp : UInt64
477476 let serverGuid : String
478477
479- init ( serviceTimestamp: UInt64 , serverGuid: String ) {
480- self . serviceTimestamp = serviceTimestamp
478+ init ( serverGuid: String ) {
481479 self . serverGuid = serverGuid
482480 }
483481
@@ -496,20 +494,26 @@ class MessageDecryptDeduplicationRecord: Codable, FetchableRecord, PersistableRe
496494 transaction: SDSAnyWriteTransaction ,
497495 skipCull: Bool = false
498496 ) -> Outcome {
499- deduplicate ( serviceTimestamp: encryptedEnvelope. serverTimestamp,
497+ deduplicate ( envelopeTimestamp: encryptedEnvelope. timestamp,
498+ serviceTimestamp: encryptedEnvelope. serverTimestamp,
500499 serverGuid: encryptedEnvelope. serverGuid,
501500 transaction: transaction,
502501 skipCull: skipCull)
503502 }
504503
505504 public static func deduplicate(
505+ envelopeTimestamp: UInt64 ,
506506 serviceTimestamp: UInt64 ,
507507 serverGuid: String ? ,
508508 transaction: SDSAnyWriteTransaction ,
509509 skipCull: Bool = false
510510 ) -> Outcome {
511+ guard envelopeTimestamp > 0 else {
512+ owsFailDebug ( " Invalid envelopeTimestamp. " )
513+ return . nonDuplicate
514+ }
511515 guard serviceTimestamp > 0 else {
512- owsFailDebug ( " Missing serviceTimestamp." )
516+ owsFailDebug ( " Invalid serviceTimestamp." )
513517 return . nonDuplicate
514518 }
515519 guard let serverGuid = serverGuid? . nilIfEmpty else {
@@ -527,21 +531,20 @@ class MessageDecryptDeduplicationRecord: Codable, FetchableRecord, PersistableRe
527531 return try Bool . fetchOne ( transaction. unwrapGrdbWrite. database, sql: sql, arguments: arguments) ?? false
528532 } ( )
529533 guard !isDuplicate else {
530- Logger . warn ( " Discarding duplicate envelope with serviceTimestamp: \( serviceTimestamp) , serverGuid: \( serverGuid) " )
534+ Logger . warn ( " Discarding duplicate envelope with envelopeTimestamp: \( envelopeTimestamp ) , serviceTimestamp: \( serviceTimestamp) , serverGuid: \( serverGuid) " )
531535 return . duplicate
532536 }
533537
534538 // No existing record found. Create a new one and insert it.
535- let record = MessageDecryptDeduplicationRecord ( serviceTimestamp: serviceTimestamp,
536- serverGuid: serverGuid)
539+ let record = MessageDecryptDeduplicationRecord ( serverGuid: serverGuid)
537540 try record. insert ( transaction. unwrapGrdbWrite. database)
538541
539542 if !skipCull, shouldCull ( ) {
540- cull ( latestServiceTimestamp : serviceTimestamp , transaction: transaction)
543+ cull ( transaction: transaction)
541544 }
542545
543546 if DebugFlags . internalLogging {
544- Logger . info ( " Proceeding with serviceTimestamp: \( serviceTimestamp) , serverGuid: \( serverGuid) " )
547+ Logger . info ( " Proceeding with envelopeTimestamp: \( envelopeTimestamp ) , serviceTimestamp: \( serviceTimestamp) , serverGuid: \( serverGuid) " )
545548 }
546549 return . nonDuplicate
547550 } catch {
@@ -553,34 +556,23 @@ class MessageDecryptDeduplicationRecord: Codable, FetchableRecord, PersistableRe
553556 }
554557
555558 static let maxRecordCount : UInt = 1000
556- static let maxRecordAgeMs : UInt64 = 5 * kMinuteInMs
557-
558- private static func cull( latestServiceTimestamp: UInt64 ,
559- transaction: SDSAnyWriteTransaction ) {
560- let count1 = recordCount ( transaction: transaction)
561-
562- // Client and service time might not match; use service timestamps for
563- // all record bookkeeping.
564- let recordExpirationTimestamp = latestServiceTimestamp - maxRecordAgeMs
565- let sql = """
566- DELETE FROM MessageDecryptDeduplication
567- WHERE serviceTimestamp < ?;
568- """
569- transaction. unwrapGrdbWrite. executeUpdate ( sql: sql, arguments: [ recordExpirationTimestamp] )
570-
571- let count2 = recordCount ( transaction: transaction)
572- if count1 != count2 {
573- Logger . info ( " Culled by timestamp: \( count1) -> \( count2) " )
574- }
575559
576- guard count2 > maxRecordCount else {
560+ static let cullCount = AtomicUInt ( 0 )
561+
562+ private static func cull( transaction: SDSAnyWriteTransaction ) {
563+
564+ cullCount. increment ( )
565+
566+ let oldCount = recordCount ( transaction: transaction)
567+
568+ guard oldCount > maxRecordCount else {
577569 return
578570 }
579571
580572 do {
581573 // It is sufficient to cull by record count in batches.
582574 // The batch size must be larger than our cull frequency to bound total record count.
583- let cullCount : Int = min ( Int ( cullFrequency) * 2 , Int ( count2 ) - Int( maxRecordCount) )
575+ let cullCount : Int = min ( Int ( cullFrequency) * 2 , Int ( oldCount ) - Int( maxRecordCount) )
584576
585577 Logger . info ( " Culling \( cullCount) records. " )
586578
@@ -592,11 +584,11 @@ class MessageDecryptDeduplicationRecord: Codable, FetchableRecord, PersistableRe
592584 try record. delete ( transaction. unwrapGrdbWrite. database)
593585 }
594586
595- let count3 = recordCount ( transaction: transaction)
596- if count2 != count3 {
597- Logger . info ( " Culled by count: \( count2 ) -> \( count3 ) " )
587+ let newCount = recordCount ( transaction: transaction)
588+ if oldCount != newCount {
589+ Logger . info ( " Culled by count: \( oldCount ) -> \( newCount ) " )
598590 }
599- owsAssertDebug ( count3 <= maxRecordCount)
591+ owsAssertDebug ( newCount <= maxRecordCount)
600592 } catch {
601593 owsFailDebug ( " Error: \( error) " )
602594 }
0 commit comments