PeerID 12/n: GossipSyncManager (#751)

* Noise types use PeerID

* Fix tests

* Extract `NoiseSessionManager` into a separate file

* Extract `NoiseSessionState` into a separate file

* Remove `failed` state from `NoiseSessionState`

* Extract `NoiseSessionError` into a separate file

* PeerID 12/n: `GossipSyncManager`
This commit is contained in:
Islam
2025-10-05 15:53:57 +02:00
committed by GitHub
parent 03c357f048
commit 2673d28686
3 changed files with 20 additions and 20 deletions
+7 -7
View File
@@ -1706,7 +1706,7 @@ final class BLEService: NSObject {
if (packet.ttl == self.messageTTL) && (isNewPeer || isReconnectedPeer) { if (packet.ttl == self.messageTTL) && (isNewPeer || isReconnectedPeer) {
self.delegate?.didConnectToPeer(peerID) self.delegate?.didConnectToPeer(peerID)
// Schedule initial unicast sync to this peer // Schedule initial unicast sync to this peer
self.gossipSyncManager?.scheduleInitialSyncToPeer(peerID, delaySeconds: 1.0) self.gossipSyncManager?.scheduleInitialSyncToPeer(PeerID(str: peerID), delaySeconds: 1.0)
} }
self.requestPeerDataPublish() self.requestPeerDataPublish()
@@ -1744,7 +1744,7 @@ final class BLEService: NSObject {
SecureLogger.warning("⚠️ Malformed REQUEST_SYNC from \(peerID)", category: .session) SecureLogger.warning("⚠️ Malformed REQUEST_SYNC from \(peerID)", category: .session)
return return
} }
gossipSyncManager?.handleRequestSync(fromPeerID: peerID, request: req) gossipSyncManager?.handleRequestSync(from: PeerID(str: peerID), request: req)
} }
// Mention parsing moved to ChatViewModel // Mention parsing moved to ChatViewModel
@@ -1940,7 +1940,7 @@ final class BLEService: NSObject {
peers.removeValue(forKey: peerID) peers.removeValue(forKey: peerID)
} }
// Remove any stored announcement for sync purposes // Remove any stored announcement for sync purposes
gossipSyncManager?.removeAnnouncementForPeer(peerID) gossipSyncManager?.removeAnnouncementForPeer(PeerID(str: peerID))
// Send on main thread // Send on main thread
notifyUI { [weak self] in notifyUI { [weak self] in
guard let self = self else { return } guard let self = self else { return }
@@ -2252,7 +2252,7 @@ final class BLEService: NSObject {
if age > retention { if age > retention {
SecureLogger.debug("🗑️ Removing stale peer after reachability window: \(peerID) (\(peer.nickname))", category: .session) SecureLogger.debug("🗑️ Removing stale peer after reachability window: \(peerID) (\(peer.nickname))", category: .session)
// Also remove any stored announcement from sync candidates // Also remove any stored announcement from sync candidates
gossipSyncManager?.removeAnnouncementForPeer(peerID) gossipSyncManager?.removeAnnouncementForPeer(PeerID(str: peerID))
peers.removeValue(forKey: peerID) peers.removeValue(forKey: peerID)
removedOfflineCount += 1 removedOfflineCount += 1
} }
@@ -2424,11 +2424,11 @@ extension BLEService: GossipSyncManager.Delegate {
} }
} }
func sendPacket(to peerID: String, packet: BitchatPacket) { func sendPacket(to peerID: PeerID, packet: BitchatPacket) {
if DispatchQueue.getSpecific(key: messageQueueKey) != nil { if DispatchQueue.getSpecific(key: messageQueueKey) != nil {
sendPacketDirected(packet, to: peerID) sendPacketDirected(packet, to: peerID.id)
} else { } else {
messageQueue.async { [weak self] in self?.sendPacketDirected(packet, to: peerID) } messageQueue.async { [weak self] in self?.sendPacketDirected(packet, to: peerID.id) }
} }
} }
+12 -12
View File
@@ -4,7 +4,7 @@ import Foundation
final class GossipSyncManager { final class GossipSyncManager {
protocol Delegate: AnyObject { protocol Delegate: AnyObject {
func sendPacket(_ packet: BitchatPacket) func sendPacket(_ packet: BitchatPacket)
func sendPacket(to peerID: String, packet: BitchatPacket) func sendPacket(to peerID: PeerID, packet: BitchatPacket)
func signPacketForBroadcast(_ packet: BitchatPacket) -> BitchatPacket func signPacketForBroadcast(_ packet: BitchatPacket) -> BitchatPacket
} }
@@ -45,7 +45,7 @@ final class GossipSyncManager {
periodicTimer?.cancel(); periodicTimer = nil periodicTimer?.cancel(); periodicTimer = nil
} }
func scheduleInitialSyncToPeer(_ peerID: String, delaySeconds: TimeInterval = 5.0) { func scheduleInitialSyncToPeer(_ peerID: PeerID, delaySeconds: TimeInterval = 5.0) {
queue.asyncAfter(deadline: .now() + delaySeconds) { [weak self] in queue.asyncAfter(deadline: .now() + delaySeconds) { [weak self] in
self?.sendRequestSync(to: peerID) self?.sendRequestSync(to: peerID)
} }
@@ -101,10 +101,10 @@ final class GossipSyncManager {
delegate?.sendPacket(signed) delegate?.sendPacket(signed)
} }
private func sendRequestSync(to peerID: String) { private func sendRequestSync(to peerID: PeerID) {
let payload = buildGcsPayload() let payload = buildGcsPayload()
var recipient = Data() var recipient = Data()
var temp = peerID var temp = peerID.id
while temp.count >= 2 && recipient.count < 8 { while temp.count >= 2 && recipient.count < 8 {
let hexByte = String(temp.prefix(2)) let hexByte = String(temp.prefix(2))
if let b = UInt8(hexByte, radix: 16) { recipient.append(b) } if let b = UInt8(hexByte, radix: 16) { recipient.append(b) }
@@ -123,13 +123,13 @@ final class GossipSyncManager {
delegate?.sendPacket(to: peerID, packet: signed) delegate?.sendPacket(to: peerID, packet: signed)
} }
func handleRequestSync(fromPeerID: String, request: RequestSyncPacket) { func handleRequestSync(from peerID: PeerID, request: RequestSyncPacket) {
queue.async { [weak self] in queue.async { [weak self] in
self?._handleRequestSync(fromPeerID: fromPeerID, request: request) self?._handleRequestSync(from: peerID, request: request)
} }
} }
private func _handleRequestSync(fromPeerID: String, request: RequestSyncPacket) { private func _handleRequestSync(from peerID: PeerID, request: RequestSyncPacket) {
// Decode GCS into sorted set and prepare membership checker // Decode GCS into sorted set and prepare membership checker
let sorted = GCSFilter.decodeToSortedSet(p: request.p, m: request.m, data: request.data) let sorted = GCSFilter.decodeToSortedSet(p: request.p, m: request.m, data: request.data)
func mightContain(_ id: Data) -> Bool { func mightContain(_ id: Data) -> Bool {
@@ -144,7 +144,7 @@ final class GossipSyncManager {
if !mightContain(idBytes) { if !mightContain(idBytes) {
var toSend = pkt var toSend = pkt
toSend.ttl = 0 toSend.ttl = 0
delegate?.sendPacket(to: fromPeerID, packet: toSend) delegate?.sendPacket(to: peerID, packet: toSend)
} }
} }
@@ -155,7 +155,7 @@ final class GossipSyncManager {
if !mightContain(idBytes) { if !mightContain(idBytes) {
var toSend = pkt var toSend = pkt
toSend.ttl = 0 toSend.ttl = 0
delegate?.sendPacket(to: fromPeerID, packet: toSend) delegate?.sendPacket(to: peerID, packet: toSend)
} }
} }
} }
@@ -185,14 +185,14 @@ final class GossipSyncManager {
} }
// Explicit removal hook for LEAVE/stale peer // Explicit removal hook for LEAVE/stale peer
func removeAnnouncementForPeer(_ peerID: String) { func removeAnnouncementForPeer(_ peerID: PeerID) {
queue.async { [weak self] in queue.async { [weak self] in
self?._removeAnnouncementForPeer(peerID) self?._removeAnnouncementForPeer(peerID)
} }
} }
private func _removeAnnouncementForPeer(_ peerID: String) { private func _removeAnnouncementForPeer(_ peerID: PeerID) {
let normalizedPeerID = peerID.lowercased() let normalizedPeerID = peerID.id.lowercased()
_ = latestAnnouncementByPeer.removeValue(forKey: normalizedPeerID) _ = latestAnnouncementByPeer.removeValue(forKey: normalizedPeerID)
// Remove messages from this peer // Remove messages from this peer
+1 -1
View File
@@ -60,7 +60,7 @@ private final class RecordingDelegate: GossipSyncManager.Delegate {
onSend?() onSend?()
} }
func sendPacket(to peerID: String, packet: BitchatPacket) { func sendPacket(to peerID: PeerID, packet: BitchatPacket) {
sendPacket(packet) sendPacket(packet)
} }