Files
amethyst/quic
Claude 59ecdd8488 fix: audit fixes in the relay client, event cache, QUIC and geode
Each fix comes with a test that fails without it.

quartz
- Publish retry no longer reconnects the whole relay pool: one relay's
  hang-up tore down every healthy socket, re-sending every REQ and AUTH.
- PoolEventOutboxState: OKs from different relays arrive on different
  threads; unguarded updates lost acks (7 of 32 in one test round), so
  the event stayed in the outbox and was re-sent on every reconnect.
- subscribeAsFlow/fetchAsFlow conflate: a burst filled the 64-slot buffer
  and the newest (complete) list was the one dropped.
- Event/template/rumor deserializers matched field names by hashCode
  alone; "jE" replaced an event's "id".

commons
- BasicBundledUpdate lost an invalidation arriving during the repeat
  run, leaving a screen's REQ unsent until something else invalidated.
- Deleting an addressable's old version by id removed the current one.
- Skip the whole-cache scan for deletions that name no addresses.
- Verify before the anti-spam check, so a forged copy cannot get the real
  note dropped as its duplicate.
- Note.removeZap/removeZapPayment take the lock the add paths take.

quic
- QuicReader bounds check overflowed on a peer-chosen length near
  Int.MAX_VALUE (skip even left a negative position).
- Any unexpected exception from a datagram now closes the connection
  instead of escaping the read loop to the process's crash handler.
- The loss timer runs under streamsLock, like the ACK path that mutates
  the same sent-packet map.

geode
- Cap WebSocket frames (1 MiB default): Ktor allocates a frame's buffer
  from its header, so one header could cost 2 GB.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CqrnnGz1CgmRfxqku9BcTk
2026-10-13 02:59:31 +00:00
..