mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-25 13:45:20 +00:00
* Mesh robustness: link-aware fragmentation, relay jitter, connection budget, adaptive scanning; fix BLE queue deadlock - Link-aware fragmentation using per-link write/notify limits - Directed fragments for one-to-one; exclude from relays - Add relay jitter with cancel-on-duplicate to reduce floods - Cap central links and rate-limit connect attempts with queue - Foreground duty-cycled scanning when connected; continuous when isolated - Fix deadlock by avoiding sync on BLE queue when already on it - Silence Keychain var->let warnings * Mesh: add relay jitter; dynamic RSSI threshold; candidate scoring/backoff; fix misplaced lines in BLEService extension * macOS UI: restore mesh peer list when geohash feature is iOS-only by moving mesh list outside iOS switch (ContentView) * ContentView: add macOS mesh peer list under #else to fix missing People section on macOS * Refactor People section: extract MeshPeerList and GeohashPeopleList into separate views to reduce SwiftUI type-checking complexity; integrate in ContentView * BLE: prevent re-fragmentation loops; UI: darker mesh blue + first-row spacing in peer list * Mesh flood/battery: probabilistic relays, adaptive TTL caps, fragment pacing + scan pause, assembly cap; enable relayed DMs with direct-first then flood fallback. * Refactor BLEService broadcast: split pad policy, encrypted/direct-first handler, and link-aware sender; simplify broadcastPacket to delegate by type. * Extract relay decision into RelayController with RelayDecision; simplify handleReceivedPacket to use it. * Move RelayController and RelayDecision into their own file under Services; keep BLEService leaner. * UI: adjust mesh blue to a darker, less purple tone; apply consistently for count and #mesh badge. * Project: include RelayController.swift in target and sync project file changes. --------- Co-authored-by: jack <jackjackbits@users.noreply.github.com>
48 lines
1.6 KiB
Swift
48 lines
1.6 KiB
Swift
import Foundation
|
|
|
|
// RelayDecision encapsulates a single relay scheduling choice.
|
|
struct RelayDecision {
|
|
let shouldRelay: Bool
|
|
let newTTL: UInt8
|
|
let delayMs: Int
|
|
}
|
|
|
|
// RelayController centralizes flood control policy for relays.
|
|
struct RelayController {
|
|
static func decide(ttl: UInt8,
|
|
senderIsSelf: Bool,
|
|
isEncrypted: Bool,
|
|
isDirectedFragment: Bool,
|
|
isHandshake: Bool,
|
|
degree: Int,
|
|
highDegreeThreshold: Int) -> RelayDecision {
|
|
// Suppress obvious non-relays
|
|
if ttl <= 1 || senderIsSelf { return RelayDecision(shouldRelay: false, newTTL: ttl, delayMs: 0) }
|
|
|
|
// Degree-aware probability to reduce floods in dense graphs
|
|
let baseProb: Double
|
|
switch degree {
|
|
case 0...2: baseProb = 1.0
|
|
case 3...4: baseProb = 0.9
|
|
case 5...6: baseProb = 0.7
|
|
case 7...9: baseProb = 0.55
|
|
default: baseProb = 0.45
|
|
}
|
|
var prob = baseProb
|
|
if isHandshake { prob = max(0.3, baseProb - 0.2) }
|
|
|
|
// Sample a forwarding decision
|
|
let shouldRelay = Double.random(in: 0...1) <= prob
|
|
|
|
// TTL clamping in dense graphs
|
|
let ttlCap: UInt8 = degree >= highDegreeThreshold ? 3 : 5
|
|
let clamped = max(1, min(ttl, ttlCap))
|
|
let newTTL = clamped &- 1
|
|
|
|
// Short jitter to desynchronize rebroadcasts
|
|
let delayMs = Int.random(in: 20...80)
|
|
return RelayDecision(shouldRelay: shouldRelay, newTTL: newTTL, delayMs: delayMs)
|
|
}
|
|
}
|
|
|