Merge pull request #829 from TheCodeSmith404/fix/panic-mode-memory-purge-807

fix(panic): clear in-memory networking caches, router outbox, and Nostr queues on panic wipe (#807)
This commit is contained in:
callebtc 2026-07-30 16:33:06 +02:00 committed by GitHub
commit aaac810f4f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 42 additions and 1 deletions

View File

@ -1583,6 +1583,7 @@ class BluetoothMeshService(private val context: Context) : TransportBridgeServic
securityManager.clearAllData() securityManager.clearAllData()
peerManager.clearAllPeers() peerManager.clearAllPeers()
peerManager.clearAllFingerprints() peerManager.clearAllFingerprints()
try { gossipSyncManager.clear() } catch (_: Exception) { }
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "Error clearing mesh service internal data: ${e.message}") Log.e(TAG, "Error clearing mesh service internal data: ${e.message}")
} }

View File

@ -987,6 +987,7 @@ class MeshCore(
securityManager.clearAllData() securityManager.clearAllData()
peerManager.clearAllPeers() peerManager.clearAllPeers()
peerManager.clearAllFingerprints() peerManager.clearAllFingerprints()
try { gossipSyncManager.clear() } catch (_: Exception) { }
} }
fun clearAllEncryptionData() { fun clearAllEncryptionData() {

View File

@ -679,6 +679,24 @@ class NostrRelayManager private constructor() {
Log.e(TAG, "Failed to clear subscriptions: ${e.message}") Log.e(TAG, "Failed to clear subscriptions: ${e.message}")
} }
} }
/**
* Clear all subscription tracking, deduplication cache, message queue, and connections for panic mode.
*/
fun clearAllOnPanic() {
try {
val wasConnected = desiredConnected.get()
clearAllSubscriptions()
clearDeduplicationCache()
disconnect()
if (wasConnected) {
desiredConnected.set(true)
}
Log.w(TAG, "🚨 Cleared NostrRelayManager subscriptions, cache, and connections for panic mode")
} catch (e: Exception) {
Log.e(TAG, "Failed to clear NostrRelayManager on panic: ${e.message}")
}
}
/** /**
* Get detailed status for all relays * Get detailed status for all relays

View File

@ -136,6 +136,7 @@ object MeshServiceHolder {
@Synchronized @Synchronized
fun clear() { fun clear() {
android.util.Log.d(TAG, "Clearing BluetoothMeshService from holder") android.util.Log.d(TAG, "Clearing BluetoothMeshService from holder")
try { sharedGossipSyncManager?.clear() } catch (_: Exception) { }
try { sharedGossipSyncManager?.stop() } catch (_: Exception) { } try { sharedGossipSyncManager?.stop() } catch (_: Exception) { }
sharedGossipSyncManager = null sharedGossipSyncManager = null
activeGossipOwners.clear() activeGossipOwners.clear()

View File

@ -99,6 +99,12 @@ class MessageRouter private constructor(
startOutboxScheduler() startOutboxScheduler()
} }
fun clearAll() {
outbox.clear()
retryState.clear()
Log.d(TAG, "Cleared all MessageRouter outbox messages and retry state")
}
// Listener for favorites changes to flush outbox when npub mapping appears/changes // Listener for favorites changes to flush outbox when npub mapping appears/changes
private val favoriteListener = object: com.bitchat.android.favorites.FavoritesChangeListener { private val favoriteListener = object: com.bitchat.android.favorites.FavoritesChangeListener {

View File

@ -79,6 +79,15 @@ class GossipSyncManager(
cleanupJob?.cancel(); cleanupJob = null cleanupJob?.cancel(); cleanupJob = null
} }
@Synchronized
fun clear() {
synchronized(messages) {
messages.clear()
}
latestAnnouncementByPeer.clear()
Log.d(TAG, "Cleared all gossip sync messages and announcements")
}
fun scheduleInitialSync(delayMs: Long = 5_000L) { fun scheduleInitialSync(delayMs: Long = 5_000L) {
scope.launch(Dispatchers.IO) { scope.launch(Dispatchers.IO) {
delay(delayMs) delay(delayMs)

View File

@ -1445,10 +1445,13 @@ class ChatViewModel(
dataManager.clearAllData() dataManager.clearAllData()
conversationListPreferences.clearAll() conversationListPreferences.clearAll()
// Clear seen message store // Clear seen message store and MessageRouter outbox
try { try {
com.bitchat.android.services.SeenMessageStore.getInstance(getApplication()).clear() com.bitchat.android.services.SeenMessageStore.getInstance(getApplication()).clear()
} catch (_: Exception) { } } catch (_: Exception) { }
try {
com.bitchat.android.services.MessageRouter.tryGetInstance()?.clearAll()
} catch (_: Exception) { }
// Clear all cryptographic data // Clear all cryptographic data
clearAllCryptographicData() clearAllCryptographicData()

View File

@ -119,6 +119,8 @@ class GeohashViewModel(
geoTimer = null geoTimer = null
try { NostrIdentityBridge.clearAllAssociations(getApplication()) } catch (_: Exception) {} try { NostrIdentityBridge.clearAllAssociations(getApplication()) } catch (_: Exception) {}
NostrBackgroundRuntime.resetSubscriptions() NostrBackgroundRuntime.resetSubscriptions()
try { com.bitchat.android.nostr.NostrRelayManager.getInstance(getApplication()).clearAllOnPanic() } catch (_: Exception) {}
try { com.bitchat.android.nostr.LocationNotesManager.getInstance().stop() } catch (_: Exception) {}
} }
fun sendGeohashMessage(content: String, channel: com.bitchat.android.geohash.GeohashChannel, myPeerID: String, nickname: String?) { fun sendGeohashMessage(content: String, channel: com.bitchat.android.geohash.GeohashChannel, myPeerID: String, nickname: String?) {