Updated the code to take the service node offset into account when setting timestamps

pull/761/head
Morgan Pretty 2 years ago
parent ff65c84504
commit f7199b4c44

@ -206,7 +206,7 @@ public final class SessionCall: CurrentCallProtocol, WebRTCSessionDelegate {
let thread: SessionThread = try? SessionThread.fetchOne(db, id: sessionId)
else { return }
let timestampMs: Int64 = Int64(floor(Date().timeIntervalSince1970 * 1000))
let timestampMs: Int64 = SnodeAPI.currentOffsetTimestampMs()
let message: CallMessage = CallMessage(
uuid: self.uuid,
kind: .preOffer,

@ -409,7 +409,7 @@ extension ConversationVC:
// flags appropriately
let threadId: String = self.viewModel.threadData.threadId
let oldThreadShouldBeVisible: Bool = (self.viewModel.threadData.threadShouldBeVisible == true)
let sentTimestampMs: Int64 = Int64(floor((Date().timeIntervalSince1970 * 1000)))
let sentTimestampMs: Int64 = SnodeAPI.currentOffsetTimestampMs()
let linkPreviewDraft: LinkPreviewDraft? = snInputView.linkPreviewInfo?.draft
let quoteModel: QuotedReplyModel? = snInputView.quoteDraftInfo?.model
@ -534,7 +534,7 @@ extension ConversationVC:
// flags appropriately
let threadId: String = self.viewModel.threadData.threadId
let oldThreadShouldBeVisible: Bool = (self.viewModel.threadData.threadShouldBeVisible == true)
let sentTimestampMs: Int64 = Int64(floor((Date().timeIntervalSince1970 * 1000)))
let sentTimestampMs: Int64 = SnodeAPI.currentOffsetTimestampMs()
// If this was a message request then approve it
approveMessageRequestIfNeeded(
@ -640,7 +640,7 @@ extension ConversationVC:
threadVariant: threadVariant,
threadIsMessageRequest: threadIsMessageRequest,
direction: .outgoing,
timestampMs: Int64(floor(Date().timeIntervalSince1970 * 1000))
timestampMs: SnodeAPI.currentOffsetTimestampMs()
)
if needsToStartTypingIndicator {
@ -1219,7 +1219,7 @@ extension ConversationVC:
guard !threadIsMessageRequest else { return }
// Perform local rate limiting (don't allow more than 20 reactions within 60 seconds)
let sentTimestamp: Int64 = Int64(floor(Date().timeIntervalSince1970 * 1000))
let sentTimestamp: Int64 = SnodeAPI.currentOffsetTimestampMs()
let recentReactionTimestamps: [Int64] = General.cache.wrappedValue.recentReactionTimestamps
guard
@ -2044,7 +2044,7 @@ extension ConversationVC:
// Create URL
let directory: String = OWSTemporaryDirectory()
let fileName: String = "\(Int64(floor(Date().timeIntervalSince1970 * 1000))).m4a"
let fileName: String = "\(SnodeAPI.currentOffsetTimestampMs()).m4a"
let url: URL = URL(fileURLWithPath: directory).appendingPathComponent(fileName)
// Set up audio session
@ -2285,7 +2285,7 @@ extension ConversationVC {
for: self.viewModel.threadData.threadId,
threadVariant: self.viewModel.threadData.threadVariant,
isNewThread: false,
timestampMs: Int64(floor(Date().timeIntervalSince1970 * 1000))
timestampMs: SnodeAPI.currentOffsetTimestampMs()
)
}

@ -168,7 +168,7 @@ class ThreadDisappearingMessagesViewModel: SessionTableViewModel<ThreadDisappear
authorId: getUserHexEncodedPublicKey(db),
variant: .infoDisappearingMessagesUpdate,
body: config.messageInfoString(with: nil),
timestampMs: Int64(floor(Date().timeIntervalSince1970 * 1000))
timestampMs: SnodeAPI.currentOffsetTimestampMs()
)
.inserted(db)

@ -622,7 +622,7 @@ class ThreadSettingsViewModel: SessionTableViewModel<ThreadSettingsViewModel.Nav
threadId: thread.id,
authorId: userId,
variant: .standardOutgoing,
timestampMs: Int64(floor(Date().timeIntervalSince1970 * 1000)),
timestampMs: SnodeAPI.currentOffsetTimestampMs(),
expiresInSeconds: try? DisappearingMessagesConfiguration
.select(.durationSeconds)
.filter(id: userId)

@ -532,7 +532,7 @@ class NotificationActionHandler {
authorId: getUserHexEncodedPublicKey(db),
variant: .standardOutgoing,
body: replyText,
timestampMs: Int64(floor(Date().timeIntervalSince1970 * 1000)),
timestampMs: SnodeAPI.currentOffsetTimestampMs(),
hasMention: Interaction.isUserMentioned(db, threadId: threadId, body: replyText),
expiresInSeconds: try? DisappearingMessagesConfiguration
.select(.durationSeconds)

@ -5,6 +5,7 @@ import GRDB
import PromiseKit
import WebRTC
import SessionUtilitiesKit
import SessionSnodeKit
public protocol WebRTCSessionDelegate: AnyObject {
var videoCapturer: RTCVideoCapturer { get }
@ -179,7 +180,7 @@ public final class WebRTCSession : NSObject, RTCPeerConnectionDelegate {
uuid: uuid,
kind: .offer,
sdps: [ sdp.sdp ],
sentTimestampMs: UInt64(floor(Date().timeIntervalSince1970 * 1000))
sentTimestampMs: SnodeAPI.currentTimestampMs()
),
interactionId: nil,
in: thread

@ -1286,7 +1286,7 @@ enum _003_YDBToGRDBMigration: Migration {
// so we can reverse-engineer an approximate timestamp by extracting it from
// the id (this value is unlikely to match exactly though)
let fallbackTimestamp: UInt64 = legacyJob.id
.map { UInt64($0.prefix("\(Int(Date().timeIntervalSince1970 * 1000))".count)) }
.map { UInt64($0.prefix("\(SnodeAPI.currentOffsetTimestampMs())".count)) }
.defaulting(to: 0)
let legacyIdentifier: String = identifier(
for: threadId,
@ -1657,7 +1657,7 @@ enum _003_YDBToGRDBMigration: Migration {
state: .invalid,
contentType: "",
byteCount: 0,
creationTimestamp: Date().timeIntervalSince1970,
creationTimestamp: (TimeInterval(SnodeAPI.currentOffsetTimestampMs()) / 1000),
sourceFilename: nil,
downloadUrl: nil,
localRelativeFilePath: nil,

@ -1,12 +1,13 @@
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
import Foundation
import AVFAudio
import AVFoundation
import GRDB
import PromiseKit
import SignalCoreKit
import SessionUtilitiesKit
import AVFAudio
import AVFoundation
import SessionSnodeKit
public struct Attachment: Codable, Identifiable, Equatable, Hashable, FetchableRecord, PersistableRecord, TableRecord, ColumnExpressible {
public static var databaseTableName: String { "attachment" }
@ -1114,7 +1115,7 @@ extension Attachment {
state: .uploaded,
creationTimestamp: (
updatedAttachment?.creationTimestamp ??
Date().timeIntervalSince1970
(TimeInterval(SnodeAPI.currentOffsetTimestampMs()) / 1000)
),
downloadUrl: "\(FileServerAPI.server)/files/\(fileId)"
)

@ -3,6 +3,7 @@
import Foundation
import GRDB
import SessionUtilitiesKit
import SessionSnodeKit
/// We can rely on the unique constraints within the `Interaction` table to prevent duplicate `VisibleMessage`
/// values from being processed, but some control messages dont have an associated interaction - this table provides
@ -168,7 +169,10 @@ internal extension ControlMessageProcessRecord {
self.threadId = threadId
self.timestampMs = timestampMs
self.serverExpirationTimestamp = (Date().timeIntervalSince1970 + ControlMessageProcessRecord.defaultExpirationSeconds)
self.serverExpirationTimestamp = (
(TimeInterval(SnodeAPI.currentOffsetTimestampMs()) / 1000) +
ControlMessageProcessRecord.defaultExpirationSeconds
)
}
/// This method should only be used for records created during migration from the legacy
@ -179,7 +183,8 @@ internal extension ControlMessageProcessRecord {
/// clean out these excessive entries after `defaultExpirationSeconds`)
static func generateLegacyProcessRecords(_ db: Database, receivedMessageTimestamps: [Int64]) throws {
let defaultExpirationTimestamp: TimeInterval = (
Date().timeIntervalSince1970 + ControlMessageProcessRecord.defaultExpirationSeconds
(TimeInterval(SnodeAPI.currentOffsetTimestampMs()) / 1000) +
ControlMessageProcessRecord.defaultExpirationSeconds
)
try receivedMessageTimestamps.forEach { timestampMs in

@ -3,6 +3,7 @@
import Foundation
import GRDB
import SessionUtilitiesKit
import SessionSnodeKit
public struct DisappearingMessagesConfiguration: Codable, Identifiable, Equatable, FetchableRecord, PersistableRecord, TableRecord, ColumnExpressible {
public static var databaseTableName: String { "disappearingMessagesConfiguration" }
@ -206,7 +207,7 @@ public class SMKDisappearingMessagesConfiguration: NSObject {
authorId: getUserHexEncodedPublicKey(db),
variant: .infoDisappearingMessagesUpdate,
body: config.messageInfoString(with: nil),
timestampMs: Int64(floor(Date().timeIntervalSince1970 * 1000))
timestampMs: SnodeAPI.currentOffsetTimestampMs()
)
.inserted(db)

@ -4,6 +4,7 @@ import Foundation
import GRDB
import Sodium
import SessionUtilitiesKit
import SessionSnodeKit
public struct Interaction: Codable, Identifiable, Equatable, FetchableRecord, MutablePersistableRecord, TableRecord, ColumnExpressible {
public static var databaseTableName: String { "interaction" }
@ -298,7 +299,7 @@ public struct Interaction: Codable, Identifiable, Equatable, FetchableRecord, Mu
self.timestampMs = timestampMs
self.receivedAtTimestampMs = {
switch variant {
case .standardIncoming, .standardOutgoing: return Int64(Date().timeIntervalSince1970 * 1000)
case .standardIncoming, .standardOutgoing: return SnodeAPI.currentOffsetTimestampMs()
/// For TSInteractions which are not `standardIncoming` and `standardOutgoing` use the `timestampMs` value
default: return timestampMs
@ -458,7 +459,7 @@ public extension Interaction {
job: DisappearingMessagesJob.updateNextRunIfNeeded(
db,
interactionIds: interactionIds,
startedAtMs: (Date().timeIntervalSince1970 * 1000)
startedAtMs: TimeInterval(SnodeAPI.currentOffsetTimestampMs())
)
)

@ -6,6 +6,7 @@ import PromiseKit
import AFNetworking
import SignalCoreKit
import SessionUtilitiesKit
import SessionSnodeKit
public struct LinkPreview: Codable, Equatable, Hashable, FetchableRecord, PersistableRecord, TableRecord, ColumnExpressible {
public static var databaseTableName: String { "linkPreview" }
@ -60,7 +61,7 @@ public struct LinkPreview: Codable, Equatable, Hashable, FetchableRecord, Persis
public init(
url: String,
timestamp: TimeInterval = LinkPreview.timestampFor(
sentTimestampMs: (Date().timeIntervalSince1970 * 1000) // Default to now
sentTimestampMs: TimeInterval(SnodeAPI.currentOffsetTimestampMs()) // Default to now
),
variant: Variant = .standard,
title: String?,

@ -4,6 +4,7 @@ import Foundation
import GRDB
import Sodium
import SessionUtilitiesKit
import SessionSnodeKit
public struct SessionThread: Codable, Identifiable, Equatable, FetchableRecord, PersistableRecord, TableRecord, ColumnExpressible {
public static var databaseTableName: String { "thread" }
@ -104,7 +105,7 @@ public struct SessionThread: Codable, Identifiable, Equatable, FetchableRecord,
public init(
id: String,
variant: Variant,
creationDateTimestamp: TimeInterval = Date().timeIntervalSince1970,
creationDateTimestamp: TimeInterval = (TimeInterval(SnodeAPI.currentOffsetTimestampMs()) / 1000),
shouldBeVisible: Bool = false,
isPinned: Bool = false,
messageDraft: String? = nil,

@ -145,7 +145,7 @@ public enum AttachmentDownloadJob: JobExecutor {
_ = try attachment
.with(
state: .downloaded,
creationTimestamp: Date().timeIntervalSince1970,
creationTimestamp: (TimeInterval(SnodeAPI.currentOffsetTimestampMs()) / 1000),
localRelativeFilePath: (
attachment.localRelativeFilePath ??
Attachment.localRelativeFilePath(from: attachment.originalFilePath)

@ -3,6 +3,7 @@
import Foundation
import GRDB
import SessionUtilitiesKit
import SessionSnodeKit
public enum DisappearingMessagesJob: JobExecutor {
public static let maxFailureCount: Int = -1
@ -17,7 +18,7 @@ public enum DisappearingMessagesJob: JobExecutor {
deferred: @escaping (Job) -> ()
) {
// The 'backgroundTask' gets captured and cleared within the 'completion' block
let timestampNowMs: TimeInterval = ceil(Date().timeIntervalSince1970 * 1000)
let timestampNowMs: TimeInterval = TimeInterval(SnodeAPI.currentOffsetTimestampMs())
var backgroundTask: OWSBackgroundTask? = OWSBackgroundTask(label: #function)
let updatedJob: Job? = Storage.shared.write { db in

@ -259,7 +259,10 @@ public extension Message {
return try processRawReceivedMessage(
db,
envelope: envelope,
serverExpirationTimestamp: (Date().timeIntervalSince1970 + ControlMessageProcessRecord.defaultExpirationSeconds),
serverExpirationTimestamp: (
(TimeInterval(SnodeAPI.currentOffsetTimestampMs()) / 1000) +
ControlMessageProcessRecord.defaultExpirationSeconds
),
serverHash: serverHash,
handleClosedGroupKeyUpdateMessages: true
)
@ -275,7 +278,10 @@ public extension Message {
let processedMessage: ProcessedMessage? = try processRawReceivedMessage(
db,
envelope: envelope,
serverExpirationTimestamp: (Date().timeIntervalSince1970 + ControlMessageProcessRecord.defaultExpirationSeconds),
serverExpirationTimestamp: (
(TimeInterval(SnodeAPI.currentOffsetTimestampMs()) / 1000) +
ControlMessageProcessRecord.defaultExpirationSeconds
),
serverHash: nil,
handleClosedGroupKeyUpdateMessages: false
)
@ -407,7 +413,7 @@ public extension Message {
let count: Int64 = rawReaction.you ? rawReaction.count - 1 : rawReaction.count
let timestampMs: Int64 = Int64(floor((Date().timeIntervalSince1970 * 1000)))
let timestampMs: Int64 = SnodeAPI.currentOffsetTimestampMs()
let maxLength: Int = shouldAddSelfReaction ? 4 : 5
let desiredReactorIds: [String] = reactors
.filter { $0 != blindedUserPublicKey && $0 != userPublicKey } // Remove current user for now, will add back if needed

@ -4,6 +4,7 @@ import Foundation
import GRDB
import WebRTC
import SessionUtilitiesKit
import SessionSnodeKit
extension MessageReceiver {
public static func handleCallMessage(_ db: Database, message: CallMessage) throws {
@ -189,7 +190,7 @@ extension MessageReceiver {
body: String(data: messageInfoData, encoding: .utf8),
timestampMs: (
message.sentTimestamp.map { Int64($0) } ??
Int64(floor(Date().timeIntervalSince1970 * 1000))
SnodeAPI.currentOffsetTimestampMs()
)
)
.inserted(db)
@ -235,7 +236,7 @@ extension MessageReceiver {
)
let timestampMs: Int64 = (
message.sentTimestamp.map { Int64($0) } ??
Int64(floor(Date().timeIntervalSince1970 * 1000))
SnodeAPI.currentOffsetTimestampMs()
)
guard let messageInfoData: Data = try? JSONEncoder().encode(messageInfo) else { return nil }

@ -4,6 +4,7 @@ import Foundation
import GRDB
import Sodium
import SessionUtilitiesKit
import SessionSnodeKit
extension MessageReceiver {
public static func handleClosedGroupControlMessage(_ db: Database, _ message: ClosedGroupControlMessage) throws {
@ -135,7 +136,7 @@ extension MessageReceiver {
threadId: groupPublicKey,
publicKey: Data(encryptionKeyPair.publicKey),
secretKey: Data(encryptionKeyPair.secretKey),
receivedTimestamp: Date().timeIntervalSince1970
receivedTimestamp: (TimeInterval(SnodeAPI.currentOffsetTimestampMs()) / 1000)
).insert(db)
// Start polling
@ -196,7 +197,7 @@ extension MessageReceiver {
threadId: groupPublicKey,
publicKey: proto.publicKey.removingIdPrefixIfNeeded(),
secretKey: proto.privateKey,
receivedTimestamp: Date().timeIntervalSince1970
receivedTimestamp: (TimeInterval(SnodeAPI.currentOffsetTimestampMs()) / 1000)
).insert(db)
}
catch {
@ -231,7 +232,7 @@ extension MessageReceiver {
.infoMessage(db, sender: sender),
timestampMs: (
message.sentTimestamp.map { Int64($0) } ??
Int64(floor(Date().timeIntervalSince1970 * 1000))
SnodeAPI.currentOffsetTimestampMs()
)
).inserted(db)
}
@ -307,7 +308,7 @@ extension MessageReceiver {
.infoMessage(db, sender: sender),
timestampMs: (
message.sentTimestamp.map { Int64($0) } ??
Int64(floor(Date().timeIntervalSince1970 * 1000))
SnodeAPI.currentOffsetTimestampMs()
)
).inserted(db)
}
@ -383,7 +384,7 @@ extension MessageReceiver {
.infoMessage(db, sender: sender),
timestampMs: (
message.sentTimestamp.map { Int64($0) } ??
Int64(floor(Date().timeIntervalSince1970 * 1000))
SnodeAPI.currentOffsetTimestampMs()
)
).inserted(db)
}
@ -461,7 +462,7 @@ extension MessageReceiver {
.infoMessage(db, sender: sender),
timestampMs: (
message.sentTimestamp.map { Int64($0) } ??
Int64(floor(Date().timeIntervalSince1970 * 1000))
SnodeAPI.currentOffsetTimestampMs()
)
).inserted(db)
}

@ -2,6 +2,7 @@
import Foundation
import GRDB
import SessionSnodeKit
extension MessageReceiver {
internal static func handleDataExtractionNotification(_ db: Database, message: DataExtractionNotification) throws {
@ -24,7 +25,7 @@ extension MessageReceiver {
}(),
timestampMs: (
message.sentTimestamp.map { Int64($0) } ??
Int64(floor(Date().timeIntervalSince1970 * 1000))
SnodeAPI.currentOffsetTimestampMs()
)
).inserted(db)
}

@ -4,6 +4,7 @@ import Foundation
import GRDB
import SignalCoreKit
import SessionUtilitiesKit
import SessionSnodeKit
extension MessageReceiver {
internal static func handleMessageRequestResponse(
@ -123,7 +124,7 @@ extension MessageReceiver {
variant: .infoMessageRequestAccepted,
timestampMs: (
message.sentTimestamp.map { Int64($0) } ??
Int64(floor(Date().timeIntervalSince1970 * 1000))
SnodeAPI.currentOffsetTimestampMs()
)
).inserted(db)
}

@ -6,6 +6,7 @@ import Sodium
import Curve25519Kit
import PromiseKit
import SessionUtilitiesKit
import SessionSnodeKit
extension MessageSender {
public static var distributingKeyPairs: Atomic<[String: [ClosedGroupKeyPair]]> = Atomic([:])
@ -24,7 +25,7 @@ extension MessageSender {
let membersAsData = members.map { Data(hex: $0) }
let admins = [ userPublicKey ]
let adminsAsData = admins.map { Data(hex: $0) }
let formationTimestamp: TimeInterval = Date().timeIntervalSince1970
let formationTimestamp: TimeInterval = (TimeInterval(SnodeAPI.currentOffsetTimestampMs()) / 1000)
let thread: SessionThread = try SessionThread
.fetchOrCreate(db, id: groupPublicKey, variant: .closedGroup)
try ClosedGroup(
@ -91,7 +92,7 @@ extension MessageSender {
threadId: groupPublicKey,
publicKey: encryptionKeyPair.publicKey,
secretKey: encryptionKeyPair.privateKey,
receivedTimestamp: Date().timeIntervalSince1970
receivedTimestamp: (TimeInterval(SnodeAPI.currentOffsetTimestampMs()) / 1000)
).insert(db)
// Notify the PN server
@ -110,7 +111,7 @@ extension MessageSender {
threadId: thread.id,
authorId: userPublicKey,
variant: .infoClosedGroupCreated,
timestampMs: Int64(floor(Date().timeIntervalSince1970 * 1000))
timestampMs: SnodeAPI.currentOffsetTimestampMs()
).inserted(db)
// Start polling
@ -142,7 +143,7 @@ extension MessageSender {
threadId: closedGroup.threadId,
publicKey: legacyNewKeyPair.publicKey,
secretKey: legacyNewKeyPair.privateKey,
receivedTimestamp: Date().timeIntervalSince1970
receivedTimestamp: (TimeInterval(SnodeAPI.currentOffsetTimestampMs()) / 1000)
)
// Distribute it
@ -230,7 +231,7 @@ extension MessageSender {
body: ClosedGroupControlMessage.Kind
.nameChange(name: name)
.infoMessage(db, sender: userPublicKey),
timestampMs: Int64(floor(Date().timeIntervalSince1970 * 1000))
timestampMs: SnodeAPI.currentOffsetTimestampMs()
).inserted(db)
guard let interactionId: Int64 = interaction.id else { throw StorageError.objectNotSaved }
@ -330,7 +331,7 @@ extension MessageSender {
body: ClosedGroupControlMessage.Kind
.membersAdded(members: addedMembers.map { Data(hex: $0) })
.infoMessage(db, sender: userPublicKey),
timestampMs: Int64(floor(Date().timeIntervalSince1970 * 1000))
timestampMs: SnodeAPI.currentOffsetTimestampMs()
).inserted(db)
guard let interactionId: Int64 = interaction.id else { throw StorageError.objectNotSaved }
@ -431,7 +432,7 @@ extension MessageSender {
body: ClosedGroupControlMessage.Kind
.membersRemoved(members: removedMembers.map { Data(hex: $0) })
.infoMessage(db, sender: userPublicKey),
timestampMs: Int64(floor(Date().timeIntervalSince1970 * 1000))
timestampMs: SnodeAPI.currentOffsetTimestampMs()
).inserted(db)
guard let newInteractionId: Int64 = interaction.id else { throw StorageError.objectNotSaved }
@ -496,7 +497,7 @@ extension MessageSender {
body: ClosedGroupControlMessage.Kind
.memberLeft
.infoMessage(db, sender: userPublicKey),
timestampMs: Int64(floor(Date().timeIntervalSince1970 * 1000))
timestampMs: SnodeAPI.currentOffsetTimestampMs()
).inserted(db)
guard let interactionId: Int64 = interaction.id else {

@ -5,6 +5,7 @@ import GRDB
import Sodium
import SignalCoreKit
import SessionUtilitiesKit
import SessionSnodeKit
public enum MessageReceiver {
private static var lastEncryptionKeyPairRequest: [String: Date] = [:]
@ -144,7 +145,7 @@ public enum MessageReceiver {
message.sender = sender
message.recipient = userPublicKey
message.sentTimestamp = envelope.timestamp
message.receivedTimestamp = UInt64((Date().timeIntervalSince1970) * 1000)
message.receivedTimestamp = SnodeAPI.currentTimestampMs()
message.groupPublicKey = groupPublicKey
message.openGroupServerMessageId = openGroupMessageServerId.map { UInt64($0) }

@ -67,7 +67,7 @@ public final class MessageSender {
let (promise, seal) = Promise<Void>.pending()
let userPublicKey: String = getUserHexEncodedPublicKey(db)
let isMainAppActive: Bool = (UserDefaults.sharedLokiProject?[.isMainAppActive]).defaulting(to: false)
let messageSendTimestamp: Int64 = Int64(floor(Date().timeIntervalSince1970 * 1000))
let messageSendTimestamp: Int64 = SnodeAPI.currentOffsetTimestampMs()
// Set the timestamp, sender and recipient
message.sentTimestamp = (
@ -322,7 +322,7 @@ public final class MessageSender {
// Set the timestamp, sender and recipient
if message.sentTimestamp == nil { // Visible messages will already have their sent timestamp set
message.sentTimestamp = UInt64(floor(Date().timeIntervalSince1970 * 1000))
message.sentTimestamp = SnodeAPI.currentTimestampMs()
}
switch destination {
@ -472,7 +472,7 @@ public final class MessageSender {
// Set the timestamp, sender and recipient
if message.sentTimestamp == nil { // Visible messages will already have their sent timestamp set
message.sentTimestamp = UInt64(floor(Date().timeIntervalSince1970 * 1000))
message.sentTimestamp = SnodeAPI.currentTimestampMs()
}
message.sender = userPublicKey
@ -617,7 +617,7 @@ public final class MessageSender {
job: DisappearingMessagesJob.updateNextRunIfNeeded(
db,
interaction: interaction,
startedAtMs: (Date().timeIntervalSince1970 * 1000)
startedAtMs: TimeInterval(SnodeAPI.currentOffsetTimestampMs())
)
)
}
@ -636,7 +636,10 @@ public final class MessageSender {
}
}(),
message: message,
serverExpirationTimestamp: (Date().timeIntervalSince1970 + ControlMessageProcessRecord.defaultExpirationSeconds)
serverExpirationTimestamp: (
(TimeInterval(SnodeAPI.currentOffsetTimestampMs()) / 1000) +
ControlMessageProcessRecord.defaultExpirationSeconds
)
)?.insert(db)
// Sync the message if:

@ -3,6 +3,7 @@
import Foundation
import GRDB
import SessionUtilitiesKit
import SessionSnodeKit
public class TypingIndicators {
// MARK: - Direction
@ -41,7 +42,7 @@ public class TypingIndicators {
self.threadId = threadId
self.direction = direction
self.timestampMs = (timestampMs ?? Int64(floor(Date().timeIntervalSince1970 * 1000)))
self.timestampMs = (timestampMs ?? SnodeAPI.currentOffsetTimestampMs())
}
fileprivate func start(_ db: Database) {

@ -196,7 +196,7 @@ final class ThreadPickerVC: UIViewController, UITableViewDataSource, UITableView
authorId: getUserHexEncodedPublicKey(db),
variant: .standardOutgoing,
body: body,
timestampMs: Int64(floor(Date().timeIntervalSince1970 * 1000)),
timestampMs: SnodeAPI.currentOffsetTimestampMs(),
hasMention: Interaction.isUserMentioned(db, threadId: threadId, body: body),
expiresInSeconds: try? DisappearingMessagesConfiguration
.select(.durationSeconds)

@ -93,7 +93,7 @@ public extension SnodeReceivedMessageInfo {
return try SnodeReceivedMessageInfo
.select(Column.rowID)
.filter(SnodeReceivedMessageInfo.Columns.key == key(for: snode, publicKey: publicKey, namespace: namespace))
.filter(SnodeReceivedMessageInfo.Columns.expirationDateMs <= (Date().timeIntervalSince1970 * 1000))
.filter(SnodeReceivedMessageInfo.Columns.expirationDateMs <= SnodeAPI.currentOffsetTimestampMs())
.asRequest(of: Int64.self)
.fetchAll(db)
}
@ -122,7 +122,7 @@ public extension SnodeReceivedMessageInfo {
SnodeReceivedMessageInfo.Columns.wasDeletedOrInvalid == false
)
.filter(SnodeReceivedMessageInfo.Columns.key == key(for: snode, publicKey: publicKey, namespace: namespace))
.filter(SnodeReceivedMessageInfo.Columns.expirationDateMs > (Date().timeIntervalSince1970 * 1000))
.filter(SnodeReceivedMessageInfo.Columns.expirationDateMs > SnodeAPI.currentOffsetTimestampMs())
.order(SnodeReceivedMessageInfo.Columns.id.desc)
.fetchOne(db)

@ -23,6 +23,14 @@ public final class SnodeAPI {
///
/// - Note: Should only be accessed from `Threading.workQueue` to avoid race conditions.
public static var clockOffset: Atomic<Int64> = Atomic(0)
public static func currentOffsetTimestampMs() -> Int64 {
return (
Int64(floor(Date().timeIntervalSince1970 * 1000)) +
SnodeAPI.clockOffset.wrappedValue
)
}
/// - Note: Should only be accessed from `Threading.workQueue` to avoid race conditions.
public static var swarmCache: Atomic<[String: Set<Snode>]> = Atomic([:])
@ -546,7 +554,7 @@ public final class SnodeAPI {
let lastHash = SnodeReceivedMessageInfo.fetchLastNotExpired(for: snode, namespace: namespace, associatedWith: publicKey)?.hash ?? ""
// Construct signature
let timestamp = UInt64(Int64(floor(Date().timeIntervalSince1970 * 1000)) + SnodeAPI.clockOffset.wrappedValue)
let timestamp = UInt64(SnodeAPI.currentOffsetTimestampMs())
let ed25519PublicKey = userED25519KeyPair.publicKey.toHexString()
let namespaceVerificationString = (namespace == defaultNamespace ? "" : String(namespace))
@ -647,7 +655,7 @@ public final class SnodeAPI {
}
// Construct signature
let timestamp = UInt64(Int64(floor(Date().timeIntervalSince1970 * 1000)) + SnodeAPI.clockOffset.wrappedValue)
let timestamp = UInt64(SnodeAPI.currentOffsetTimestampMs())
let ed25519PublicKey = userED25519KeyPair.publicKey.toHexString()
guard

Loading…
Cancel
Save