From fc860e395712931b635667ca6311745e53d1e227 Mon Sep 17 00:00:00 2001 From: Morgan Pretty Date: Tue, 30 Aug 2022 09:45:40 +1000 Subject: [PATCH] Added fixes and defensive coding for a number of crashes Fixed a crash which could occur due to multithreaded dependency access Fixed a crash which could occur if the 'keyWindow' wasn't set on the LandingVC in time since we were force-unwrapping Fixed a crash which could occur due to multithreaded swarm cache access Fixed the broken unit tests --- Session/Onboarding/LandingVC.swift | 2 +- .../Open Groups/OpenGroupManager.swift | 10 ++-- .../Sending & Receiving/Pollers/Poller.swift | 2 +- .../Utilities/SMKDependencies.swift | 54 +++++++++---------- .../Open Groups/OpenGroupAPISpec.swift | 6 ++- .../Open Groups/OpenGroupManagerSpec.swift | 22 +++++--- .../_TestUtilities/DependencyExtensions.swift | 26 ++++----- .../_TestUtilities/MockGeneralCache.swift | 5 ++ .../_TestUtilities/MockOGMCache.swift | 5 ++ .../OGMDependencyExtensions.swift | 28 +++++----- SessionSnodeKit/SnodeAPI.swift | 16 +++--- .../General/Dependencies.swift | 40 ++++++++------ 12 files changed, 123 insertions(+), 93 deletions(-) diff --git a/Session/Onboarding/LandingVC.swift b/Session/Onboarding/LandingVC.swift index 2a34fff7d..0bfd0c755 100644 --- a/Session/Onboarding/LandingVC.swift +++ b/Session/Onboarding/LandingVC.swift @@ -65,7 +65,7 @@ final class LandingVC: BaseVC { linkButtonContainer.set(.height, to: Values.onboardingButtonBottomOffset) linkButtonContainer.addSubview(linkButton) linkButton.center(.horizontal, in: linkButtonContainer) - let isIPhoneX = (UIApplication.shared.keyWindow!.safeAreaInsets.bottom > 0) + let isIPhoneX = ((UIApplication.shared.keyWindow?.safeAreaInsets.bottom ?? 0) > 0) linkButton.centerYAnchor.constraint(equalTo: linkButtonContainer.centerYAnchor, constant: isIPhoneX ? -4 : 0).isActive = true // Button stack view let buttonStackView = UIStackView(arrangedSubviews: [ registerButton, restoreButton ]) diff --git a/SessionMessagingKit/Open Groups/OpenGroupManager.swift b/SessionMessagingKit/Open Groups/OpenGroupManager.swift index 4364a4dff..c6db9bce9 100644 --- a/SessionMessagingKit/Open Groups/OpenGroupManager.swift +++ b/SessionMessagingKit/Open Groups/OpenGroupManager.swift @@ -19,9 +19,9 @@ public protocol OGMCacheType { var hasPerformedInitialPoll: [String: Bool] { get set } var timeSinceLastPoll: [String: TimeInterval] { get set } - func getTimeSinceLastOpen(using dependencies: Dependencies) -> TimeInterval - var pendingChanges: [OpenGroupAPI.PendingChange] { get set } + + func getTimeSinceLastOpen(using dependencies: Dependencies) -> TimeInterval } // MARK: - OpenGroupManager @@ -1099,10 +1099,10 @@ public final class OpenGroupManager: NSObject { extension OpenGroupManager { public class OGMDependencies: SMKDependencies { - internal var _mutableCache: Atomic? + internal var _mutableCache: Atomic?> public var mutableCache: Atomic { get { Dependencies.getValueSettingIfNull(&_mutableCache) { OpenGroupManager.shared.mutableCache } } - set { _mutableCache = newValue } + set { _mutableCache.mutate { $0 = newValue } } } public var cache: OGMCacheType { return mutableCache.wrappedValue } @@ -1123,7 +1123,7 @@ extension OpenGroupManager { standardUserDefaults: UserDefaultsType? = nil, date: Date? = nil ) { - _mutableCache = cache + _mutableCache = Atomic(cache) super.init( onionApi: onionApi, diff --git a/SessionMessagingKit/Sending & Receiving/Pollers/Poller.swift b/SessionMessagingKit/Sending & Receiving/Pollers/Poller.swift index 02a3d139a..4d6c3580a 100644 --- a/SessionMessagingKit/Sending & Receiving/Pollers/Poller.swift +++ b/SessionMessagingKit/Sending & Receiving/Pollers/Poller.swift @@ -89,7 +89,7 @@ public final class Poller { private func pollNextSnode(seal: Resolver) { let userPublicKey = getUserHexEncodedPublicKey() - let swarm = SnodeAPI.swarmCache[userPublicKey] ?? [] + let swarm = SnodeAPI.swarmCache.wrappedValue[userPublicKey] ?? [] let unusedSnodes = swarm.subtracting(usedSnodes) guard !unusedSnodes.isEmpty else { diff --git a/SessionMessagingKit/Utilities/SMKDependencies.swift b/SessionMessagingKit/Utilities/SMKDependencies.swift index f7b8f4498..d4f32efae 100644 --- a/SessionMessagingKit/Utilities/SMKDependencies.swift +++ b/SessionMessagingKit/Utilities/SMKDependencies.swift @@ -6,58 +6,58 @@ import SessionSnodeKit import SessionUtilitiesKit public class SMKDependencies: Dependencies { - internal var _onionApi: OnionRequestAPIType.Type? + internal var _onionApi: Atomic public var onionApi: OnionRequestAPIType.Type { get { Dependencies.getValueSettingIfNull(&_onionApi) { OnionRequestAPI.self } } - set { _onionApi = newValue } + set { _onionApi.mutate { $0 = newValue } } } - internal var _sodium: SodiumType? + internal var _sodium: Atomic public var sodium: SodiumType { get { Dependencies.getValueSettingIfNull(&_sodium) { Sodium() } } - set { _sodium = newValue } + set { _sodium.mutate { $0 = newValue } } } - internal var _box: BoxType? + internal var _box: Atomic public var box: BoxType { get { Dependencies.getValueSettingIfNull(&_box) { sodium.getBox() } } - set { _box = newValue } + set { _box.mutate { $0 = newValue } } } - internal var _genericHash: GenericHashType? + internal var _genericHash: Atomic public var genericHash: GenericHashType { get { Dependencies.getValueSettingIfNull(&_genericHash) { sodium.getGenericHash() } } - set { _genericHash = newValue } + set { _genericHash.mutate { $0 = newValue } } } - internal var _sign: SignType? + internal var _sign: Atomic public var sign: SignType { get { Dependencies.getValueSettingIfNull(&_sign) { sodium.getSign() } } - set { _sign = newValue } + set { _sign.mutate { $0 = newValue } } } - internal var _aeadXChaCha20Poly1305Ietf: AeadXChaCha20Poly1305IetfType? + internal var _aeadXChaCha20Poly1305Ietf: Atomic public var aeadXChaCha20Poly1305Ietf: AeadXChaCha20Poly1305IetfType { get { Dependencies.getValueSettingIfNull(&_aeadXChaCha20Poly1305Ietf) { sodium.getAeadXChaCha20Poly1305Ietf() } } - set { _aeadXChaCha20Poly1305Ietf = newValue } + set { _aeadXChaCha20Poly1305Ietf.mutate { $0 = newValue } } } - internal var _ed25519: Ed25519Type? + internal var _ed25519: Atomic public var ed25519: Ed25519Type { get { Dependencies.getValueSettingIfNull(&_ed25519) { Ed25519Wrapper() } } - set { _ed25519 = newValue } + set { _ed25519.mutate { $0 = newValue } } } - internal var _nonceGenerator16: NonceGenerator16ByteType? + internal var _nonceGenerator16: Atomic public var nonceGenerator16: NonceGenerator16ByteType { get { Dependencies.getValueSettingIfNull(&_nonceGenerator16) { OpenGroupAPI.NonceGenerator16Byte() } } - set { _nonceGenerator16 = newValue } + set { _nonceGenerator16.mutate { $0 = newValue } } } - internal var _nonceGenerator24: NonceGenerator24ByteType? + internal var _nonceGenerator24: Atomic public var nonceGenerator24: NonceGenerator24ByteType { get { Dependencies.getValueSettingIfNull(&_nonceGenerator24) { OpenGroupAPI.NonceGenerator24Byte() } } - set { _nonceGenerator24 = newValue } + set { _nonceGenerator24.mutate { $0 = newValue } } } // MARK: - Initialization @@ -77,15 +77,15 @@ public class SMKDependencies: Dependencies { standardUserDefaults: UserDefaultsType? = nil, date: Date? = nil ) { - _onionApi = onionApi - _sodium = sodium - _box = box - _genericHash = genericHash - _sign = sign - _aeadXChaCha20Poly1305Ietf = aeadXChaCha20Poly1305Ietf - _ed25519 = ed25519 - _nonceGenerator16 = nonceGenerator16 - _nonceGenerator24 = nonceGenerator24 + _onionApi = Atomic(onionApi) + _sodium = Atomic(sodium) + _box = Atomic(box) + _genericHash = Atomic(genericHash) + _sign = Atomic(sign) + _aeadXChaCha20Poly1305Ietf = Atomic(aeadXChaCha20Poly1305Ietf) + _ed25519 = Atomic(ed25519) + _nonceGenerator16 = Atomic(nonceGenerator16) + _nonceGenerator24 = Atomic(nonceGenerator24) super.init( generalCache: generalCache, diff --git a/SessionMessagingKitTests/Open Groups/OpenGroupAPISpec.swift b/SessionMessagingKitTests/Open Groups/OpenGroupAPISpec.swift index e4edc8803..3af36df80 100644 --- a/SessionMessagingKitTests/Open Groups/OpenGroupAPISpec.swift +++ b/SessionMessagingKitTests/Open Groups/OpenGroupAPISpec.swift @@ -1243,7 +1243,8 @@ class OpenGroupAPISpec: QuickSpec { whisperMods: false, whisperTo: nil, base64EncodedData: nil, - base64EncodedSignature: nil + base64EncodedSignature: nil, + reactions: nil ) override class var mockResponse: Data? { return try! JSONEncoder().encode(data) } @@ -1612,7 +1613,8 @@ class OpenGroupAPISpec: QuickSpec { whisperMods: false, whisperTo: nil, base64EncodedData: nil, - base64EncodedSignature: nil + base64EncodedSignature: nil, + reactions: nil ) override class var mockResponse: Data? { return try! JSONEncoder().encode(data) } diff --git a/SessionMessagingKitTests/Open Groups/OpenGroupManagerSpec.swift b/SessionMessagingKitTests/Open Groups/OpenGroupManagerSpec.swift index 2158aa3e6..d581ac276 100644 --- a/SessionMessagingKitTests/Open Groups/OpenGroupManagerSpec.swift +++ b/SessionMessagingKitTests/Open Groups/OpenGroupManagerSpec.swift @@ -204,7 +204,8 @@ class OpenGroupManagerSpec: QuickSpec { "AAAAAAAAAAAAAAAAAAAAA", "AA" ].joined(), - base64EncodedSignature: nil + base64EncodedSignature: nil, + reactions: nil ) testDirectMessage = OpenGroupAPI.DirectMessage( id: 128, @@ -229,6 +230,7 @@ class OpenGroupManagerSpec: QuickSpec { try testOpenGroup.insert(db) try Capability(openGroupServer: testOpenGroup.server, variant: .sogs, isMissing: false).insert(db) } + mockOGMCache.when { $0.pendingChanges }.thenReturn([]) mockGeneralCache.when { $0.encodedPublicKey }.thenReturn("05\(TestConstants.publicKey)") mockGenericHash.when { $0.hash(message: anyArray(), outputLength: any()) }.thenReturn([]) mockSodium @@ -2115,7 +2117,8 @@ class OpenGroupManagerSpec: QuickSpec { whisperMods: false, whisperTo: nil, base64EncodedData: nil, - base64EncodedSignature: nil + base64EncodedSignature: nil, + reactions: nil ) ], for: "testRoom", @@ -2175,7 +2178,8 @@ class OpenGroupManagerSpec: QuickSpec { whisperMods: false, whisperTo: nil, base64EncodedData: Data([1, 2, 3]).base64EncodedString(), - base64EncodedSignature: nil + base64EncodedSignature: nil, + reactions: nil ) ], for: "testRoom", @@ -2207,7 +2211,8 @@ class OpenGroupManagerSpec: QuickSpec { whisperMods: false, whisperTo: nil, base64EncodedData: Data([1, 2, 3]).base64EncodedString(), - base64EncodedSignature: nil + base64EncodedSignature: nil, + reactions: nil ) ], for: "testRoom", @@ -2249,7 +2254,8 @@ class OpenGroupManagerSpec: QuickSpec { whisperMods: false, whisperTo: nil, base64EncodedData: Data([1, 2, 3]).base64EncodedString(), - base64EncodedSignature: nil + base64EncodedSignature: nil, + reactions: nil ), testMessage, ], @@ -2287,7 +2293,8 @@ class OpenGroupManagerSpec: QuickSpec { whisperMods: false, whisperTo: nil, base64EncodedData: nil, - base64EncodedSignature: nil + base64EncodedSignature: nil, + reactions: nil ) ], for: "testRoom", @@ -2315,7 +2322,8 @@ class OpenGroupManagerSpec: QuickSpec { whisperMods: false, whisperTo: nil, base64EncodedData: nil, - base64EncodedSignature: nil + base64EncodedSignature: nil, + reactions: nil ) ], for: "testRoom", diff --git a/SessionMessagingKitTests/_TestUtilities/DependencyExtensions.swift b/SessionMessagingKitTests/_TestUtilities/DependencyExtensions.swift index 5c2f8de5d..51bb86598 100644 --- a/SessionMessagingKitTests/_TestUtilities/DependencyExtensions.swift +++ b/SessionMessagingKitTests/_TestUtilities/DependencyExtensions.swift @@ -23,19 +23,19 @@ extension SMKDependencies { date: Date? = nil ) -> SMKDependencies { return SMKDependencies( - onionApi: (onionApi ?? self._onionApi), - generalCache: (generalCache ?? self._generalCache), - storage: (storage ?? self._storage), - sodium: (sodium ?? self._sodium), - box: (box ?? self._box), - genericHash: (genericHash ?? self._genericHash), - sign: (sign ?? self._sign), - aeadXChaCha20Poly1305Ietf: (aeadXChaCha20Poly1305Ietf ?? self._aeadXChaCha20Poly1305Ietf), - ed25519: (ed25519 ?? self._ed25519), - nonceGenerator16: (nonceGenerator16 ?? self._nonceGenerator16), - nonceGenerator24: (nonceGenerator24 ?? self._nonceGenerator24), - standardUserDefaults: (standardUserDefaults ?? self._standardUserDefaults), - date: (date ?? self._date) + onionApi: (onionApi ?? self._onionApi.wrappedValue), + generalCache: (generalCache ?? self._generalCache.wrappedValue), + storage: (storage ?? self._storage.wrappedValue), + sodium: (sodium ?? self._sodium.wrappedValue), + box: (box ?? self._box.wrappedValue), + genericHash: (genericHash ?? self._genericHash.wrappedValue), + sign: (sign ?? self._sign.wrappedValue), + aeadXChaCha20Poly1305Ietf: (aeadXChaCha20Poly1305Ietf ?? self._aeadXChaCha20Poly1305Ietf.wrappedValue), + ed25519: (ed25519 ?? self._ed25519.wrappedValue), + nonceGenerator16: (nonceGenerator16 ?? self._nonceGenerator16.wrappedValue), + nonceGenerator24: (nonceGenerator24 ?? self._nonceGenerator24.wrappedValue), + standardUserDefaults: (standardUserDefaults ?? self._standardUserDefaults.wrappedValue), + date: (date ?? self._date.wrappedValue) ) } } diff --git a/SessionMessagingKitTests/_TestUtilities/MockGeneralCache.swift b/SessionMessagingKitTests/_TestUtilities/MockGeneralCache.swift index c47b8d6eb..bf687f6d0 100644 --- a/SessionMessagingKitTests/_TestUtilities/MockGeneralCache.swift +++ b/SessionMessagingKitTests/_TestUtilities/MockGeneralCache.swift @@ -10,4 +10,9 @@ class MockGeneralCache: Mock, GeneralCacheType { get { return accept() as? String } set { accept(args: [newValue]) } } + + var recentReactionTimestamps: [Int64] { + get { return accept() as! [Int64] } + set { accept(args: [newValue]) } + } } diff --git a/SessionMessagingKitTests/_TestUtilities/MockOGMCache.swift b/SessionMessagingKitTests/_TestUtilities/MockOGMCache.swift index 31bace48f..02caa5e85 100644 --- a/SessionMessagingKitTests/_TestUtilities/MockOGMCache.swift +++ b/SessionMessagingKitTests/_TestUtilities/MockOGMCache.swift @@ -37,6 +37,11 @@ class MockOGMCache: Mock, OGMCacheType { set { accept(args: [newValue]) } } + var pendingChanges: [OpenGroupAPI.PendingChange] { + get { return accept() as! [OpenGroupAPI.PendingChange] } + set { accept(args: [newValue]) } + } + func getTimeSinceLastOpen(using dependencies: Dependencies) -> TimeInterval { return accept(args: [dependencies]) as! TimeInterval } diff --git a/SessionMessagingKitTests/_TestUtilities/OGMDependencyExtensions.swift b/SessionMessagingKitTests/_TestUtilities/OGMDependencyExtensions.swift index d559bdfec..0d2f8cee9 100644 --- a/SessionMessagingKitTests/_TestUtilities/OGMDependencyExtensions.swift +++ b/SessionMessagingKitTests/_TestUtilities/OGMDependencyExtensions.swift @@ -24,20 +24,20 @@ extension OpenGroupManager.OGMDependencies { date: Date? = nil ) -> OpenGroupManager.OGMDependencies { return OpenGroupManager.OGMDependencies( - cache: (cache ?? self._mutableCache), - onionApi: (onionApi ?? self._onionApi), - generalCache: (generalCache ?? self._generalCache), - storage: (storage ?? self._storage), - sodium: (sodium ?? self._sodium), - box: (box ?? self._box), - genericHash: (genericHash ?? self._genericHash), - sign: (sign ?? self._sign), - aeadXChaCha20Poly1305Ietf: (aeadXChaCha20Poly1305Ietf ?? self._aeadXChaCha20Poly1305Ietf), - ed25519: (ed25519 ?? self._ed25519), - nonceGenerator16: (nonceGenerator16 ?? self._nonceGenerator16), - nonceGenerator24: (nonceGenerator24 ?? self._nonceGenerator24), - standardUserDefaults: (standardUserDefaults ?? self._standardUserDefaults), - date: (date ?? self._date) + cache: (cache ?? self._mutableCache.wrappedValue), + onionApi: (onionApi ?? self._onionApi.wrappedValue), + generalCache: (generalCache ?? self._generalCache.wrappedValue), + storage: (storage ?? self._storage.wrappedValue), + sodium: (sodium ?? self._sodium.wrappedValue), + box: (box ?? self._box.wrappedValue), + genericHash: (genericHash ?? self._genericHash.wrappedValue), + sign: (sign ?? self._sign.wrappedValue), + aeadXChaCha20Poly1305Ietf: (aeadXChaCha20Poly1305Ietf ?? self._aeadXChaCha20Poly1305Ietf.wrappedValue), + ed25519: (ed25519 ?? self._ed25519.wrappedValue), + nonceGenerator16: (nonceGenerator16 ?? self._nonceGenerator16.wrappedValue), + nonceGenerator24: (nonceGenerator24 ?? self._nonceGenerator24.wrappedValue), + standardUserDefaults: (standardUserDefaults ?? self._standardUserDefaults.wrappedValue), + date: (date ?? self._date.wrappedValue) ) } } diff --git a/SessionSnodeKit/SnodeAPI.swift b/SessionSnodeKit/SnodeAPI.swift index 2e5b5fc1f..1106f56c4 100644 --- a/SessionSnodeKit/SnodeAPI.swift +++ b/SessionSnodeKit/SnodeAPI.swift @@ -24,7 +24,7 @@ public final class SnodeAPI { /// - Note: Should only be accessed from `Threading.workQueue` to avoid race conditions. public static var clockOffset: Int64 = 0 /// - Note: Should only be accessed from `Threading.workQueue` to avoid race conditions. - public static var swarmCache: [String: Set] = [:] + public static var swarmCache: Atomic<[String: Set]> = Atomic([:]) // MARK: - Namespaces @@ -96,10 +96,11 @@ public final class SnodeAPI { private static func loadSwarmIfNeeded(for publicKey: String) { guard !loadedSwarms.contains(publicKey) else { return } - Storage.shared.read { db in - swarmCache[publicKey] = ((try? Snode.fetchSet(db, publicKey: publicKey)) ?? []) - } + let updatedCacheForKey: Set = Storage.shared + .read { db in try Snode.fetchSet(db, publicKey: publicKey) } + .defaulting(to: []) + swarmCache.mutate { $0[publicKey] = updatedCacheForKey } loadedSwarms.insert(publicKey) } @@ -107,7 +108,8 @@ public final class SnodeAPI { #if DEBUG dispatchPrecondition(condition: .onQueue(Threading.workQueue)) #endif - swarmCache[publicKey] = newValue + swarmCache.mutate { $0[publicKey] = newValue } + guard persist else { return } Storage.shared.write { db in @@ -119,7 +121,7 @@ public final class SnodeAPI { #if DEBUG dispatchPrecondition(condition: .onQueue(Threading.workQueue)) #endif - let swarmOrNil = swarmCache[publicKey] + let swarmOrNil = swarmCache.wrappedValue[publicKey] guard var swarm = swarmOrNil, let index = swarm.firstIndex(of: snode) else { return } swarm.remove(at: index) setSwarm(to: swarm, for: publicKey) @@ -460,7 +462,7 @@ public final class SnodeAPI { public static func getSwarm(for publicKey: String) -> Promise> { loadSwarmIfNeeded(for: publicKey) - if let cachedSwarm = swarmCache[publicKey], cachedSwarm.count >= minSwarmSnodeCount { + if let cachedSwarm = swarmCache.wrappedValue[publicKey], cachedSwarm.count >= minSwarmSnodeCount { return Promise> { $0.fulfill(cachedSwarm) } } diff --git a/SessionUtilitiesKit/General/Dependencies.swift b/SessionUtilitiesKit/General/Dependencies.swift index 5ac20c999..a0c3f132c 100644 --- a/SessionUtilitiesKit/General/Dependencies.swift +++ b/SessionUtilitiesKit/General/Dependencies.swift @@ -3,28 +3,28 @@ import Foundation open class Dependencies { - public var _generalCache: Atomic? + public var _generalCache: Atomic?> public var generalCache: Atomic { get { Dependencies.getValueSettingIfNull(&_generalCache) { General.cache } } - set { _generalCache = newValue } + set { _generalCache.mutate { $0 = newValue } } } - public var _storage: Storage? + public var _storage: Atomic public var storage: Storage { get { Dependencies.getValueSettingIfNull(&_storage) { Storage.shared } } - set { _storage = newValue } + set { _storage.mutate { $0 = newValue } } } - public var _standardUserDefaults: UserDefaultsType? + public var _standardUserDefaults: Atomic public var standardUserDefaults: UserDefaultsType { get { Dependencies.getValueSettingIfNull(&_standardUserDefaults) { UserDefaults.standard } } - set { _standardUserDefaults = newValue } + set { _standardUserDefaults.mutate { $0 = newValue } } } - public var _date: Date? + public var _date: Atomic public var date: Date { get { Dependencies.getValueSettingIfNull(&_date) { Date() } } - set { _date = newValue } + set { _date.mutate { $0 = newValue } } } // MARK: - Initialization @@ -35,21 +35,29 @@ open class Dependencies { standardUserDefaults: UserDefaultsType? = nil, date: Date? = nil ) { - _generalCache = generalCache - _storage = storage - _standardUserDefaults = standardUserDefaults - _date = date + _generalCache = Atomic(generalCache) + _storage = Atomic(storage) + _standardUserDefaults = Atomic(standardUserDefaults) + _date = Atomic(date) } // MARK: - Convenience - - public static func getValueSettingIfNull(_ maybeValue: inout T?, _ valueGenerator: () -> T) -> T { - guard let value: T = maybeValue else { + + public static func getValueSettingIfNull(_ maybeValue: inout Atomic, _ valueGenerator: () -> T) -> T { + guard let value: T = maybeValue.wrappedValue else { let value: T = valueGenerator() - maybeValue = value + maybeValue.mutate { $0 = value } return value } return value } + +// 0 libswiftCore.dylib 0x00000001999fd40c _swift_release_dealloc + 32 (HeapObject.cpp:703) +// 1 SessionMessagingKit 0x0000000106aa958c 0x106860000 + 2397580 +// 2 libswiftCore.dylib 0x00000001999fd424 _swift_release_dealloc + 56 (HeapObject.cpp:703) +// 3 SessionUtilitiesKit 0x0000000106cbd980 static Dependencies.getValueSettingIfNull(_:_:) + 264 (Dependencies.swift:49) +// 4 SessionMessagingKit 0x0000000106aa90f4 closure #1 in SMKDependencies.sign.getter + 112 (SMKDependencies.swift:17) +// 5 SessionUtilitiesKit 0x0000000106cbd974 static Dependencies.getValueSettingIfNull(_:_:) + 252 (Dependencies.swift:48) +// 6 SessionMessagingKit 0x000000010697aef8 specialized static OpenGroupAPI.sign(_:messageBytes:for:fallbackSigningType:using:) + 1158904 (OpenGroupAPI.swift:1190) }