mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-26 13:45:22 +00:00
Remove dead code and simplify codebase
- Remove unused BinaryEncodable protocol and BinaryMessageType enum - Delete MockNoiseSession.swift (never used in tests) - Remove all relay detection code (hardcoded to false) - Removed isRelayConnected property from BitchatPeer - Removed relayConnected case from ConnectionState enum - Cleaned up relay-related UI indicators in ContentView - Removed relay status checks from ChatViewModel - Simplified peer connection logic by removing relay layer Total: 169 lines removed across 5 files
This commit is contained in:
@@ -18,7 +18,6 @@ struct BitchatPeer: Identifiable, Equatable {
|
|||||||
// Connection state
|
// Connection state
|
||||||
enum ConnectionState {
|
enum ConnectionState {
|
||||||
case bluetoothConnected
|
case bluetoothConnected
|
||||||
case relayConnected // Connected via mesh relay (another peer)
|
|
||||||
case nostrAvailable // Mutual favorite, reachable via Nostr
|
case nostrAvailable // Mutual favorite, reachable via Nostr
|
||||||
case offline // Not connected via any transport
|
case offline // Not connected via any transport
|
||||||
}
|
}
|
||||||
@@ -26,8 +25,6 @@ struct BitchatPeer: Identifiable, Equatable {
|
|||||||
var connectionState: ConnectionState {
|
var connectionState: ConnectionState {
|
||||||
if isConnected {
|
if isConnected {
|
||||||
return .bluetoothConnected
|
return .bluetoothConnected
|
||||||
} else if isRelayConnected {
|
|
||||||
return .relayConnected
|
|
||||||
} else if favoriteStatus?.isMutual == true {
|
} else if favoriteStatus?.isMutual == true {
|
||||||
// Mutual favorites can communicate via Nostr when offline
|
// Mutual favorites can communicate via Nostr when offline
|
||||||
return .nostrAvailable
|
return .nostrAvailable
|
||||||
@@ -36,8 +33,6 @@ struct BitchatPeer: Identifiable, Equatable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var isRelayConnected: Bool = false // Set by PeerManager based on session state
|
|
||||||
|
|
||||||
var isFavorite: Bool {
|
var isFavorite: Bool {
|
||||||
favoriteStatus?.isFavorite ?? false
|
favoriteStatus?.isFavorite ?? false
|
||||||
}
|
}
|
||||||
@@ -59,8 +54,6 @@ struct BitchatPeer: Identifiable, Equatable {
|
|||||||
switch connectionState {
|
switch connectionState {
|
||||||
case .bluetoothConnected:
|
case .bluetoothConnected:
|
||||||
return "📻" // Radio icon for mesh connection
|
return "📻" // Radio icon for mesh connection
|
||||||
case .relayConnected:
|
|
||||||
return "🔗" // Chain link for relay connection
|
|
||||||
case .nostrAvailable:
|
case .nostrAvailable:
|
||||||
return "🌐" // Purple globe for Nostr
|
return "🌐" // Purple globe for Nostr
|
||||||
case .offline:
|
case .offline:
|
||||||
@@ -78,15 +71,13 @@ struct BitchatPeer: Identifiable, Equatable {
|
|||||||
noisePublicKey: Data,
|
noisePublicKey: Data,
|
||||||
nickname: String,
|
nickname: String,
|
||||||
lastSeen: Date = Date(),
|
lastSeen: Date = Date(),
|
||||||
isConnected: Bool = false,
|
isConnected: Bool = false
|
||||||
isRelayConnected: Bool = false
|
|
||||||
) {
|
) {
|
||||||
self.id = id
|
self.id = id
|
||||||
self.noisePublicKey = noisePublicKey
|
self.noisePublicKey = noisePublicKey
|
||||||
self.nickname = nickname
|
self.nickname = nickname
|
||||||
self.lastSeen = lastSeen
|
self.lastSeen = lastSeen
|
||||||
self.isConnected = isConnected
|
self.isConnected = isConnected
|
||||||
self.isRelayConnected = isRelayConnected
|
|
||||||
|
|
||||||
// Load favorite status - will be set later by the manager
|
// Load favorite status - will be set later by the manager
|
||||||
self.favoriteStatus = nil
|
self.favoriteStatus = nil
|
||||||
@@ -156,28 +147,15 @@ class PeerManager: ObservableObject {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if this peer is actually connected (not just known via relay)
|
// Check if this peer is actually connected
|
||||||
let isConnected = meshService.isPeerConnected(peerID)
|
let isConnected = meshService.isPeerConnected(peerID)
|
||||||
let isKnown = meshService.isPeerKnown(peerID)
|
|
||||||
// In a mesh network, a peer can only be relay-connected if:
|
|
||||||
// 1. We know about them (have received announce)
|
|
||||||
// 2. We're not directly connected
|
|
||||||
// 3. There are other peers that could relay (mesh peer count > 2)
|
|
||||||
// For now, disable relay detection until we have proper relay tracking
|
|
||||||
let isRelayConnected = false
|
|
||||||
|
|
||||||
// Debug logging for relay connection detection
|
|
||||||
if isKnown && !isConnected {
|
|
||||||
SecureLogger.log("Peer \(nickname) (\(peerID)): isConnected=\(isConnected), isKnown=\(isKnown), isRelayConnected=\(isRelayConnected)",
|
|
||||||
category: SecureLogger.session, level: .debug)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skip disconnected peers unless they're favorites (handled later)
|
// Skip disconnected peers unless they're favorites (handled later)
|
||||||
if !isConnected && !isRelayConnected {
|
if !isConnected {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if isConnected || isRelayConnected {
|
if isConnected {
|
||||||
connectedNicknames.insert(nickname)
|
connectedNicknames.insert(nickname)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,8 +166,7 @@ class PeerManager: ObservableObject {
|
|||||||
id: peerID,
|
id: peerID,
|
||||||
noisePublicKey: noiseKey,
|
noisePublicKey: noiseKey,
|
||||||
nickname: nickname,
|
nickname: nickname,
|
||||||
isConnected: isConnected,
|
isConnected: isConnected
|
||||||
isRelayConnected: isRelayConnected
|
|
||||||
)
|
)
|
||||||
// Set favorite status - check both by current noise key and by nickname
|
// Set favorite status - check both by current noise key and by nickname
|
||||||
if let favoriteStatus = favoritesService.getFavoriteStatus(for: noiseKey) {
|
if let favoriteStatus = favoritesService.getFavoriteStatus(for: noiseKey) {
|
||||||
@@ -211,14 +188,14 @@ class PeerManager: ObservableObject {
|
|||||||
allPeers.append(peer)
|
allPeers.append(peer)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add offline favorites (only those not currently connected/relay-connected AND that we actively favorite)
|
// Add offline favorites (only those not currently connected AND that we actively favorite)
|
||||||
|
|
||||||
for (favoriteKey, favorite) in favoritesService.favorites {
|
for (favoriteKey, favorite) in favoritesService.favorites {
|
||||||
let favoriteID = favorite.peerNoisePublicKey.hexEncodedString()
|
let favoriteID = favorite.peerNoisePublicKey.hexEncodedString()
|
||||||
|
|
||||||
// Skip if this peer is already connected or relay-connected (by nickname)
|
// Skip if this peer is already connected (by nickname)
|
||||||
if connectedNicknames.contains(favorite.peerNickname) {
|
if connectedNicknames.contains(favorite.peerNickname) {
|
||||||
SecureLogger.log(" - Skipping '\(favorite.peerNickname)' (key: \(favoriteKey.hexEncodedString())) - already connected/relay-connected",
|
SecureLogger.log(" - Skipping '\(favorite.peerNickname)' (key: \(favoriteKey.hexEncodedString())) - already connected",
|
||||||
category: SecureLogger.session, level: .debug)
|
category: SecureLogger.session, level: .debug)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -259,16 +236,12 @@ class PeerManager: ObservableObject {
|
|||||||
!(peer.displayName == "Unknown" && peer.favoriteStatus == nil)
|
!(peer.displayName == "Unknown" && peer.favoriteStatus == nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort: Connected first (direct then relay), then favorites, then alphabetical
|
// Sort: Connected first, then favorites, then alphabetical
|
||||||
allPeers.sort { lhs, rhs in
|
allPeers.sort { lhs, rhs in
|
||||||
// Direct connections first
|
// Direct connections first
|
||||||
if lhs.isConnected != rhs.isConnected {
|
if lhs.isConnected != rhs.isConnected {
|
||||||
return lhs.isConnected
|
return lhs.isConnected
|
||||||
}
|
}
|
||||||
// Then relay connections
|
|
||||||
if lhs.isRelayConnected != rhs.isRelayConnected {
|
|
||||||
return lhs.isRelayConnected
|
|
||||||
}
|
|
||||||
// Then favorites
|
// Then favorites
|
||||||
if lhs.isFavorite != rhs.isFavorite {
|
if lhs.isFavorite != rhs.isFavorite {
|
||||||
return lhs.isFavorite
|
return lhs.isFavorite
|
||||||
@@ -321,13 +294,10 @@ class PeerManager: ObservableObject {
|
|||||||
|
|
||||||
// Log each peer's status
|
// Log each peer's status
|
||||||
for peer in allPeers {
|
for peer in allPeers {
|
||||||
// Use the actual statusIcon from the peer which accounts for relay connections
|
|
||||||
let statusIcon: String
|
let statusIcon: String
|
||||||
switch peer.connectionState {
|
switch peer.connectionState {
|
||||||
case .bluetoothConnected:
|
case .bluetoothConnected:
|
||||||
statusIcon = "🟢"
|
statusIcon = "🟢"
|
||||||
case .relayConnected:
|
|
||||||
statusIcon = "🔗"
|
|
||||||
case .nostrAvailable:
|
case .nostrAvailable:
|
||||||
statusIcon = "🌐"
|
statusIcon = "🌐"
|
||||||
case .offline:
|
case .offline:
|
||||||
|
|||||||
@@ -221,18 +221,3 @@ extension Data {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Binary Message Protocol
|
|
||||||
|
|
||||||
protocol BinaryEncodable {
|
|
||||||
func toBinaryData() -> Data
|
|
||||||
static func fromBinaryData(_ data: Data) -> Self?
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Message Type Registry
|
|
||||||
|
|
||||||
enum BinaryMessageType: UInt8 {
|
|
||||||
case deliveryAck = 0x01
|
|
||||||
case readReceipt = 0x02
|
|
||||||
case noiseIdentityAnnouncement = 0x09
|
|
||||||
case noiseMessage = 0x0A
|
|
||||||
}
|
|
||||||
@@ -859,7 +859,7 @@ class ChatViewModel: ObservableObject, BitchatDelegate {
|
|||||||
// Check if this is a moon peer (we favorite them but they don't favorite us) AND they're offline
|
// Check if this is a moon peer (we favorite them but they don't favorite us) AND they're offline
|
||||||
// Only require mutual favorites for offline Nostr messaging
|
// Only require mutual favorites for offline Nostr messaging
|
||||||
if let peer = peerIndex[peerID],
|
if let peer = peerIndex[peerID],
|
||||||
peer.isFavorite && !peer.theyFavoritedUs && !peer.isConnected && !peer.isRelayConnected {
|
peer.isFavorite && !peer.theyFavoritedUs && !peer.isConnected {
|
||||||
addSystemMessage("cannot start chat with \(peerNickname): mutual favorite required for offline messaging.")
|
addSystemMessage("cannot start chat with \(peerNickname): mutual favorite required for offline messaging.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -680,12 +680,6 @@ struct ContentView: View {
|
|||||||
.font(.system(size: 10))
|
.font(.system(size: 10))
|
||||||
.foregroundColor(textColor)
|
.foregroundColor(textColor)
|
||||||
.accessibilityLabel("Connected via mesh")
|
.accessibilityLabel("Connected via mesh")
|
||||||
case .relayConnected:
|
|
||||||
// Chain link for relay connection
|
|
||||||
Image(systemName: "link")
|
|
||||||
.font(.system(size: 10))
|
|
||||||
.foregroundColor(Color.blue)
|
|
||||||
.accessibilityLabel("Connected via relay")
|
|
||||||
case .nostrAvailable:
|
case .nostrAvailable:
|
||||||
// Purple globe for mutual favorites reachable via Nostr
|
// Purple globe for mutual favorites reachable via Nostr
|
||||||
Image(systemName: "globe")
|
Image(systemName: "globe")
|
||||||
@@ -901,7 +895,7 @@ struct ContentView: View {
|
|||||||
let peerCounts = viewModel.allPeers.reduce(into: (others: 0, mesh: 0)) { counts, peer in
|
let peerCounts = viewModel.allPeers.reduce(into: (others: 0, mesh: 0)) { counts, peer in
|
||||||
guard peer.id != viewModel.meshService.myPeerID else { return }
|
guard peer.id != viewModel.meshService.myPeerID else { return }
|
||||||
|
|
||||||
let isMeshConnected = peer.isConnected || peer.isRelayConnected
|
let isMeshConnected = peer.isConnected
|
||||||
if isMeshConnected {
|
if isMeshConnected {
|
||||||
counts.mesh += 1
|
counts.mesh += 1
|
||||||
counts.others += 1
|
counts.others += 1
|
||||||
@@ -993,12 +987,6 @@ struct ContentView: View {
|
|||||||
.font(.system(size: 14))
|
.font(.system(size: 14))
|
||||||
.foregroundColor(textColor)
|
.foregroundColor(textColor)
|
||||||
.accessibilityLabel("Connected via mesh")
|
.accessibilityLabel("Connected via mesh")
|
||||||
case .relayConnected:
|
|
||||||
// Chain link for relay connection
|
|
||||||
Image(systemName: "link")
|
|
||||||
.font(.system(size: 14))
|
|
||||||
.foregroundColor(Color.blue)
|
|
||||||
.accessibilityLabel("Connected via relay")
|
|
||||||
case .nostrAvailable:
|
case .nostrAvailable:
|
||||||
// Purple globe for Nostr
|
// Purple globe for Nostr
|
||||||
Image(systemName: "globe")
|
Image(systemName: "globe")
|
||||||
|
|||||||
@@ -1,101 +0,0 @@
|
|||||||
//
|
|
||||||
// MockNoiseSession.swift
|
|
||||||
// bitchatTests
|
|
||||||
//
|
|
||||||
// This is free and unencumbered software released into the public domain.
|
|
||||||
// For more information, see <https://unlicense.org>
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import CryptoKit
|
|
||||||
@testable import bitchat
|
|
||||||
|
|
||||||
class MockNoiseSession: NoiseSession {
|
|
||||||
var mockState: NoiseSessionState = .uninitialized
|
|
||||||
var shouldFailHandshake = false
|
|
||||||
var shouldFailEncryption = false
|
|
||||||
var handshakeMessages: [Data] = []
|
|
||||||
var encryptedData: [Data] = []
|
|
||||||
var decryptedData: [Data] = []
|
|
||||||
|
|
||||||
override func getState() -> NoiseSessionState {
|
|
||||||
return mockState
|
|
||||||
}
|
|
||||||
|
|
||||||
override func isEstablished() -> Bool {
|
|
||||||
return mockState == .established
|
|
||||||
}
|
|
||||||
|
|
||||||
override func startHandshake() throws -> Data {
|
|
||||||
if shouldFailHandshake {
|
|
||||||
mockState = .failed(NoiseSessionError.handshakeFailed(TestError.testFailure("Mock handshake failure")))
|
|
||||||
throw NoiseSessionError.handshakeFailed(TestError.testFailure("Mock handshake failure"))
|
|
||||||
}
|
|
||||||
|
|
||||||
mockState = .handshaking
|
|
||||||
let handshakeData = TestHelpers.generateRandomData(length: 32)
|
|
||||||
handshakeMessages.append(handshakeData)
|
|
||||||
return handshakeData
|
|
||||||
}
|
|
||||||
|
|
||||||
override func processHandshakeMessage(_ message: Data) throws -> Data? {
|
|
||||||
if shouldFailHandshake {
|
|
||||||
mockState = .failed(NoiseSessionError.handshakeFailed(TestError.testFailure("Mock handshake failure")))
|
|
||||||
throw NoiseSessionError.handshakeFailed(TestError.testFailure("Mock handshake failure"))
|
|
||||||
}
|
|
||||||
|
|
||||||
handshakeMessages.append(message)
|
|
||||||
|
|
||||||
// Simulate handshake completion after 2 messages
|
|
||||||
if handshakeMessages.count >= 2 {
|
|
||||||
mockState = .established
|
|
||||||
return nil
|
|
||||||
} else {
|
|
||||||
let response = TestHelpers.generateRandomData(length: 48)
|
|
||||||
handshakeMessages.append(response)
|
|
||||||
return response
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override func encrypt(_ plaintext: Data) throws -> Data {
|
|
||||||
if shouldFailEncryption {
|
|
||||||
throw NoiseSessionError.notEstablished
|
|
||||||
}
|
|
||||||
|
|
||||||
guard mockState == .established else {
|
|
||||||
throw NoiseSessionError.notEstablished
|
|
||||||
}
|
|
||||||
|
|
||||||
// Simple mock encryption: prepend magic bytes and append the data
|
|
||||||
var encrypted = Data([0xDE, 0xAD, 0xBE, 0xEF])
|
|
||||||
encrypted.append(plaintext)
|
|
||||||
encryptedData.append(encrypted)
|
|
||||||
return encrypted
|
|
||||||
}
|
|
||||||
|
|
||||||
override func decrypt(_ ciphertext: Data) throws -> Data {
|
|
||||||
if shouldFailEncryption {
|
|
||||||
throw NoiseSessionError.notEstablished
|
|
||||||
}
|
|
||||||
|
|
||||||
guard mockState == .established else {
|
|
||||||
throw NoiseSessionError.notEstablished
|
|
||||||
}
|
|
||||||
|
|
||||||
// Simple mock decryption: remove magic bytes
|
|
||||||
guard ciphertext.count > 4 else {
|
|
||||||
throw TestError.testFailure("Invalid ciphertext")
|
|
||||||
}
|
|
||||||
|
|
||||||
let plaintext = ciphertext.dropFirst(4)
|
|
||||||
decryptedData.append(plaintext)
|
|
||||||
return plaintext
|
|
||||||
}
|
|
||||||
|
|
||||||
override func reset() {
|
|
||||||
mockState = .uninitialized
|
|
||||||
handshakeMessages.removeAll()
|
|
||||||
encryptedData.removeAll()
|
|
||||||
decryptedData.removeAll()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user