Feature/fragmentation fixes (#453)

* Fix fragmentation + BLE long-write + padding

- Accumulate CBATTRequest long writes by offset and decode once per central
- Decode original packet after fragment reassembly (preserve flags/compression)
- Switch MessagePadding to strict PKCS#7 and validate before unpadding
- Make BinaryProtocol.decode robust: try raw first, then unpad fallback
- Unpad frames before BLE notify; fragment when exceeding centrals' max update length
- Skip notify path when max update length < 21 bytes (protocol minimum)

Verified large PMs and announces route without decode errors and peers show reliably.

* Tests: fix weak delegate lifetime, legacy constants, and unused vars; fragment unpadded frames

- BLEServiceTests: hold strong reference to MockBitchatDelegate
- IntegrationTests: fix inline comment braces; replace removed types with test-safe values; use numeric 0x06 for legacy handshake resp checks
- BinaryProtocolTests: remove unused minResult variable
- BLEService: fragment the unpadded frame so fragments are efficient

* tests: add Noise rehandshake recovery test; document in-memory test bus and autoFlood; stabilize large-network broadcast

* tests: align suite with current behavior (compression, padding, routing, nonce); deflake and stabilize

---------

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
This commit is contained in:
jack
2025-08-19 01:22:21 +02:00
committed by GitHub
co-authored by jack
parent 4c0bb5f93a
commit a30b73dd99
14 changed files with 741 additions and 517 deletions
+13 -58
View File
@@ -18,6 +18,7 @@ final class PrivateChatE2ETests: XCTestCase {
override func setUp() {
super.setUp()
MockBLEService.resetTestBus()
// Create services
alice = createMockService(peerID: TestConstants.testPeerID1, nickname: TestConstants.testNickname1)
@@ -80,12 +81,15 @@ final class PrivateChatE2ETests: XCTestCase {
}
}
// Alice sends private message to Bob only
alice.sendPrivateMessage(
TestConstants.testMessage1,
to: TestConstants.testPeerID2,
recipientNickname: TestConstants.testNickname2
)
// Small delay to ensure connections are registered before send
DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
// Alice sends private message to Bob only
self.alice.sendPrivateMessage(
TestConstants.testMessage1,
to: TestConstants.testPeerID2,
recipientNickname: TestConstants.testNickname2
)
}
wait(for: [bobExpectation, charlieExpectation], timeout: TestConstants.shortTimeout)
}
@@ -270,58 +274,8 @@ final class PrivateChatE2ETests: XCTestCase {
// NOTE: This test relied on MessageRetryService which has been removed
func testDuplicateAckPrevention() {
simulateConnection(alice, bob)
let messageID = UUID().uuidString
var ackCount = 0
alice.packetDeliveryHandler = { packet in
if packet.type == 0x03 {
ackCount += 1
}
}
// Create message
let message = BitchatMessage(
id: messageID,
sender: TestConstants.testNickname1,
content: TestConstants.testMessage1,
timestamp: Date(),
isRelay: false,
originalSender: nil,
isPrivate: true,
recipientNickname: TestConstants.testNickname2,
senderPeerID: TestConstants.testPeerID1,
mentions: nil
)
// Generate multiple ACKs for same message
// NOTE: DeliveryTracker has been removed - this test is no longer applicable
/*
for _ in 0..<3 {
if let ack = deliveryTracker.generateAck(
for: message,
myPeerID: TestConstants.testPeerID2,
myNickname: TestConstants.testNickname2,
hopCount: 1
) {
let ackData = ack.encode()!
let ackPacket = TestHelpers.createTestPacket(
type: 0x03,
senderID: TestConstants.testPeerID2,
recipientID: TestConstants.testPeerID1,
payload: ackData
)
alice.simulateIncomingPacket(ackPacket)
}
}
*/
// Should only generate one ACK
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
XCTAssertEqual(ackCount, 1)
}
func testDuplicateAckPrevention() throws {
throw XCTSkip("DeliveryTracker/ACK flow removed; test not applicable")
}
// MARK: - Helper Methods
@@ -330,6 +284,7 @@ final class PrivateChatE2ETests: XCTestCase {
let service = MockBluetoothMeshService()
service.myPeerID = peerID
service.mockNickname = nickname
service._testRegister()
return service
}