Sync cleanups: normalize SyncTypeFlags, single announce-ID path, TODO (#1373)

Follow-ups deferred from the REQUEST_SYNC review (#1371):

- SyncTypeFlags.init(rawValue:) now masks to the union of bits that map to a
  known message type (derived from the bit↔type table, so it tracks new
  types automatically). Phantom bits from a truncated/garbled flags field —
  or a type a newer peer added — no longer live in the set as membership no
  contains() matches yet toData() re-serializes.

- GossipSyncManager stored each latest announce as (hex-id string, packet)
  and diffed announces against the stored string while every other type
  recomputed the ID via PacketIdUtil. Collapsed the store to just the packet
  and recompute the ID everywhere, removing the latent dual-path divergence.

- Documented the REQUEST_SYNC TLV table and marked fragmentIdFilter (0x06)
  with a TODO(v2): it's parsed/re-serialized but never populated or honored
  (reserved for incremental fragment sync) — finish or drop, not silent dead
  surface.

Adds SyncTypeFlags phantom-bit/round-trip tests and a GossipSyncManager test
that an announce already in the requester's filter is suppressed (guards the
recompute path). Full suite: 1034 tests pass.

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
jack
2026-07-06 21:04:14 +02:00
committed by GitHub
co-authored by jack Claude Opus 4.8
parent 7341696280
commit c2a5668569
5 changed files with 117 additions and 13 deletions
+9
View File
@@ -4,6 +4,15 @@ import Foundation
// - 0x01: P (uint8) Golomb-Rice parameter
// - 0x02: M (uint32, big-endian) hash range (N * 2^P)
// - 0x03: data (opaque) GR bitstream bytes (MSB-first)
// - 0x04: types (bitfield) SyncTypeFlags of covered message types
// - 0x05: sinceTimestamp (uint64, big-endian) oldest ts the filter covers
// - 0x06: fragmentIdFilter (utf8) reserved
//
// TODO(v2): fragmentIdFilter (0x06) is parsed and re-serialized but never
// populated or honored it's the reserved surface for incremental fragment
// sync (request the missing fragments of one file by ID instead of diffing the
// whole fragment set). Either wire it into buildGcsPayload/_handleRequestSync
// or drop the field; don't leave it as silent dead protocol surface.
struct RequestSyncPacket {
let p: Int
let m: UInt32