mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-25 02:05:19 +00:00
Wi-Fi bulk: normalize peer ID before eligibility checks
Stable/verified private chats address a peer by its full 64-hex Noise key, but the Noise session, advertised capabilities, and connection state are keyed by the short (SHA256-derived 16-hex) routing ID. sendFilePrivate resolved the Wi-Fi bulk SendCandidate with the raw peerID, so a 64-hex key made hasEstablishedSession return false; shouldOffer never selected Wi-Fi and a >BLE-cap payload cancelled as "Wi-Fi unavailable" even when the direct peer advertised .wifiBulk. Normalize with peerID.toShort() once before the session/capability checks (extracted into wifiBulkSendCandidate) and use the normalized ID for the negotiation packet and the BLE fallback too. Test: eligibility + offer path resolves when addressed by a 64-hex Noise key — the session is established under the short ID, the raw-key lookup misses it, and the normalized send path still offers Wi-Fi. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -216,6 +216,51 @@ struct BLEServiceCoreTests {
|
||||
cachedServiceUUIDs: [BLEService.serviceUUID, otherService]
|
||||
))
|
||||
}
|
||||
|
||||
// Regression: a stable/verified private chat addresses the peer by its
|
||||
// full 64-hex Noise key, but the Noise session (and capabilities/
|
||||
// connection) are keyed by the short routing ID. The Wi-Fi bulk send path
|
||||
// must normalize the ID first, or `hasEstablishedSession` misses and
|
||||
// Wi-Fi is never offered for a large payload to a direct `.wifiBulk` peer.
|
||||
@Test
|
||||
func wifiBulkEligibility_resolvesWhenAddressedBy64HexNoiseKey() throws {
|
||||
let ble = makeService()
|
||||
|
||||
let noiseKey = Data((0..<32).map { UInt8(($0 &* 7) &+ 3) })
|
||||
let fullKey = PeerID(str: noiseKey.hexEncodedString()) // 64-hex Noise key
|
||||
#expect(fullKey.noiseKey != nil)
|
||||
let shortID = fullKey.toShort() // 16-hex routing ID
|
||||
#expect(shortID != fullKey)
|
||||
|
||||
// Establish a real Noise session in the service's noise engine, keyed
|
||||
// by the short routing ID (exactly as a completed handshake would).
|
||||
let peer = NoiseEncryptionService(keychain: MockKeychain())
|
||||
let noise = ble._test_noiseService
|
||||
let m1 = try noise.initiateHandshake(with: shortID)
|
||||
let m2 = try #require(try peer.processHandshakeMessage(from: shortID, message: m1))
|
||||
let m3 = try #require(try noise.processHandshakeMessage(from: shortID, message: m2))
|
||||
_ = try peer.processHandshakeMessage(from: shortID, message: m3)
|
||||
|
||||
#expect(noise.hasEstablishedSession(with: shortID))
|
||||
// The bug in raw form: querying by the 64-hex key misses the session.
|
||||
#expect(!noise.hasEstablishedSession(with: fullKey))
|
||||
|
||||
// Register the peer as a directly-connected `.wifiBulk` neighbor.
|
||||
ble._test_registerConnectedPeer(fullKey, capabilities: [.wifiBulk])
|
||||
|
||||
let bigPayload = FileTransferLimits.maxWifiBulkPayloadBytes
|
||||
|
||||
// The send path normalizes first, so eligibility + offer resolve for
|
||||
// both the short ID and the full 64-hex Noise key.
|
||||
let viaShort = ble._test_wifiBulkSendCandidate(payloadBytes: bigPayload, to: shortID)
|
||||
let viaFull = ble._test_wifiBulkSendCandidate(payloadBytes: bigPayload, to: fullKey)
|
||||
#expect(viaShort.hasEstablishedNoiseSession)
|
||||
#expect(viaFull.hasEstablishedNoiseSession)
|
||||
#expect(viaFull.isDirectlyConnected)
|
||||
#expect(viaFull.peerCapabilities.contains(.wifiBulk))
|
||||
#expect(WifiBulkPolicy.shouldOffer(viaShort, enabled: true))
|
||||
#expect(WifiBulkPolicy.shouldOffer(viaFull, enabled: true))
|
||||
}
|
||||
}
|
||||
|
||||
private func makeService() -> BLEService {
|
||||
|
||||
Reference in New Issue
Block a user