mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-26 16:05:21 +00:00
Fix panic wipe relay and geohash state
This commit is contained in:
@@ -298,6 +298,41 @@ final class NostrRelayManager: ObservableObject {
|
||||
torReadyWaitAttempts = 0
|
||||
updateConnectionStatus()
|
||||
}
|
||||
|
||||
/// Panic wipe reset: close sockets and drop every user/session-specific
|
||||
/// relay intent without invoking old callbacks. Unlike `disconnect()`, this
|
||||
/// must not preserve subscription replay state because geohash DM handlers
|
||||
/// can capture pre-wipe Nostr private keys.
|
||||
func resetForPanicWipe() {
|
||||
connectionGeneration &+= 1
|
||||
for (_, task) in connections {
|
||||
task.cancel(with: .goingAway, reason: nil)
|
||||
}
|
||||
connections.removeAll()
|
||||
subscriptions.removeAll()
|
||||
pendingSubscriptions.removeAll()
|
||||
messageHandlers.removeAll()
|
||||
subscriptionRequestState.removeAll()
|
||||
subscribeCoalesce.removeAll()
|
||||
eoseTrackers.removeAll()
|
||||
pendingEOSECallbacks.removeAll()
|
||||
pendingTorConnectionURLs.removeAll()
|
||||
awaitingTorForConnections = false
|
||||
torReadyWaitAttempts = 0
|
||||
recentInboundEventKeys.removeAll()
|
||||
recentInboundEventKeyOrder.removeAll()
|
||||
duplicateInboundEventDropCount = 0
|
||||
duplicateInboundEventDropCountBySubscription.removeAll()
|
||||
inboundEventLogCount = 0
|
||||
Self.pendingGiftWrapIDs.removeAll()
|
||||
|
||||
messageQueueLock.lock()
|
||||
messageQueue.removeAll()
|
||||
pendingSendDropCount = 0
|
||||
messageQueueLock.unlock()
|
||||
|
||||
updateConnectionStatus()
|
||||
}
|
||||
|
||||
/// Ensure connections exist to the given relay URLs (idempotent).
|
||||
func ensureConnections(to relayUrls: [String]) {
|
||||
@@ -1170,6 +1205,18 @@ final class NostrRelayManager: ObservableObject {
|
||||
return Set(map.keys)
|
||||
}
|
||||
|
||||
var debugMessageHandlerCount: Int {
|
||||
messageHandlers.count
|
||||
}
|
||||
|
||||
var debugSubscriptionRequestCount: Int {
|
||||
subscriptionRequestState.count
|
||||
}
|
||||
|
||||
var debugPendingEOSECallbackCount: Int {
|
||||
pendingEOSECallbacks.count
|
||||
}
|
||||
|
||||
var debugDuplicateInboundEventDropCount: Int {
|
||||
duplicateInboundEventDropCount
|
||||
}
|
||||
|
||||
@@ -1158,13 +1158,25 @@ final class ChatViewModel: ObservableObject, BitchatDelegate, TransportEventDele
|
||||
// Clear selected private chat
|
||||
selectedPrivateChatPeer = nil
|
||||
|
||||
// Clear live location/geohash session state. Persisted location state
|
||||
// was wiped above, but the running view model can still be scoped to a
|
||||
// geohash channel and hold subscriptions tied to the old Nostr identity.
|
||||
activeChannel = .mesh
|
||||
setGeoChatSubscriptionID(nil)
|
||||
setGeoDmSubscriptionID(nil)
|
||||
_ = clearGeoSamplingSubs()
|
||||
cachedGeohashIdentity = nil
|
||||
nostrKeyMapping.removeAll()
|
||||
|
||||
// Clear read receipt tracking
|
||||
sentReadReceipts.removeAll()
|
||||
deduplicationService.clearAll()
|
||||
|
||||
// IMPORTANT: Clear Nostr-related state
|
||||
// Disconnect from Nostr relays and clear subscriptions
|
||||
nostrRelayManager?.disconnect()
|
||||
// Drop relay subscriptions, handlers, pending sends, and replay state.
|
||||
// Geohash DM handlers can capture pre-wipe Nostr identities, so a plain
|
||||
// disconnect is not enough here.
|
||||
NostrRelayManager.shared.resetForPanicWipe()
|
||||
nostrRelayManager = nil
|
||||
|
||||
// Clear Nostr identity associations
|
||||
|
||||
Reference in New Issue
Block a user