Add performance baselines; check dedup before verifying Nostr signatures

New PerformanceBaselineTests measure the hot paths (Nostr inbound, BLE
packet pipeline, GCS filters, delivery index, message formatting) with
deterministic fixtures and logged PERF metrics - baselines, not
assertions, so they cannot flake CI.

The suite immediately exposed that every inbound handler ran Schnorr
verification before the dedup lookup, so duplicate events - which
dominate real multi-relay traffic - each paid ~0.5ms of main-actor
crypto for nothing. All five handlers now do cheap rejects (kind, dedup
lookup) first and only record an event as processed AFTER its signature
verifies, so a forged-signature copy can never poison the dedup set and
suppress the genuine event. Gift-wrap verification also moves entirely
off the main actor with an atomic main-actor check-and-record.

Measured: duplicate-event handling 2.2k -> 1.39M events/sec (~640x);
fresh events unchanged (crypto-bound).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
jack
2026-06-10 21:11:06 +02:00
co-authored by Claude Fable 5
parent 4b287f7490
commit 80bed1f395
3 changed files with 543 additions and 8 deletions
@@ -411,11 +411,23 @@ struct ChatViewModelNostrExtensionTests {
var invalidGiftWrap = giftWrap
invalidGiftWrap.sig = String(repeating: "0", count: 128)
// Verification and recording now happen on a detached task; give the
// invalid copy time to be verified-and-rejected, then assert it never
// entered the dedup set.
viewModel.handleNostrMessage(invalidGiftWrap)
try await Task.sleep(nanoseconds: 150_000_000)
#expect(!viewModel.deduplicationService.hasProcessedNostrEvent(giftWrap.id))
viewModel.handleNostrMessage(giftWrap)
#expect(viewModel.deduplicationService.hasProcessedNostrEvent(giftWrap.id))
var recorded = false
for _ in 0..<200 {
if viewModel.deduplicationService.hasProcessedNostrEvent(giftWrap.id) {
recorded = true
break
}
try await Task.sleep(nanoseconds: 10_000_000)
}
#expect(recorded)
}
@Test @MainActor