mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-26 15:05:24 +00:00
Converts BLEAnnounceThrottle to a lock-backed class and moves myPeerID/myPeerIDData/myNickname into a lock-backed BLELocalIdentityStateStore snapshot, so announces can never observe a split peer-ID/wire-ID during panic rotation. Serializes sendAnnounce onto the messageQueue barrier and moves the panic-reset pendingNoiseSessionQueues clear onto collectionsQueue (the queue every other mutation site uses). Rebased onto main after #1431/#1432; integrates with #1431's panic-suspend structure (guard retained in both the outer sendAnnounce and the deferred worker).
58 lines
1.8 KiB
Swift
58 lines
1.8 KiB
Swift
import BitFoundation
|
|
import Foundation
|
|
import Testing
|
|
@testable import bitchat
|
|
|
|
struct BLELocalIdentityStateStoreTests {
|
|
@Test
|
|
func identityReplacementUpdatesWireBytesAtomically() throws {
|
|
let initial = PeerID(str: "0011223344556677")
|
|
let replacement = PeerID(str: "8899aabbccddeeff")
|
|
let store = BLELocalIdentityStateStore(peerID: initial, nickname: "alice")
|
|
|
|
store.replacePeerIdentity(with: replacement)
|
|
|
|
let snapshot = store.snapshot()
|
|
#expect(snapshot.peerID == replacement)
|
|
#expect(snapshot.peerIDData == Data(hexString: replacement.id))
|
|
#expect(snapshot.nickname == "alice")
|
|
}
|
|
|
|
@Test
|
|
func concurrentReadsNeverObserveSplitIdentityState() {
|
|
let peerIDs = [
|
|
PeerID(str: "0011223344556677"),
|
|
PeerID(str: "8899aabbccddeeff")
|
|
]
|
|
let store = BLELocalIdentityStateStore(peerID: peerIDs[0], nickname: "alice")
|
|
let failures = LockedFailureRecorder()
|
|
|
|
DispatchQueue.concurrentPerform(iterations: 2_000) { index in
|
|
if index.isMultiple(of: 2) {
|
|
store.replacePeerIdentity(with: peerIDs[index % peerIDs.count])
|
|
} else {
|
|
store.setNickname(index.isMultiple(of: 3) ? "alice" : "bob")
|
|
}
|
|
|
|
let snapshot = store.snapshot()
|
|
let expectedWireID = Data(hexString: snapshot.peerID.id) ?? Data()
|
|
if snapshot.peerIDData != expectedWireID {
|
|
failures.record()
|
|
}
|
|
}
|
|
|
|
#expect(!failures.hasFailure)
|
|
}
|
|
}
|
|
|
|
private final class LockedFailureRecorder: @unchecked Sendable {
|
|
private let lock = NSLock()
|
|
private var failed = false
|
|
|
|
var hasFailure: Bool { lock.withLock { failed } }
|
|
|
|
func record() {
|
|
lock.withLock { failed = true }
|
|
}
|
|
}
|