fix(extension): widen peerId generation to 16 hex chars (64-bit)

8 hex chars (32-bit) gives ~7% collision probability at the relay's
25k-peer capacity and ~1% at 10k peers. A same-room collision silently
triggers the dedup path and kicks the older session with a confusing
'Another session with this ID joined' error.

16 hex chars (64-bit) drops collision probability to ~1e-10 even at one
million peers. The server's JOIN_ROOM sanitizer already clamps peerId to
16 chars, so no server change is needed. Fully backward compatible:

- Existing clients keep their persisted 8-char peerId (only newly
  generated IDs change).
- Mixed 8-char + 16-char ID rooms work — both fit the server's 16-char
  clamp.
- No protocol change on the wire.

Birthday-paradox reference (computed, not estimated):
  32-bit @ 10k peers:  1.16%
  32-bit @ 25k peers:  7.02%
  64-bit @ 25k peers:  ~0.017e-9%
This commit is contained in:
KoalaDev
2026-06-28 08:29:59 +02:00
parent 9fc58dca4b
commit 5379778a20
+10 -2
View File
@@ -339,7 +339,14 @@ function updateLocalPeerState(targetPeerId, updates) {
async function getPeerId() {
const data = await chrome.storage.local.get(['peerId']);
if (data.peerId) return data.peerId;
const newId = self.crypto.randomUUID().substring(0, 8);
// 16 hex chars = 64 bits. At a busy relay (25k concurrent peers) the 32-bit
// (8-hex) generation would hit ~7% collision probability per snapshot —
// and a same-room collision triggers our dedup path, kicking the older
// session with a confusing error. 16 hex chars drops the probability to
// ~1e-10 even at a million peers, and the server already clamps peerId to
// 16 chars (server/index.js JOIN_ROOM sanitizer). Existing persisted 8-char
// IDs continue to work — this only affects newly-generated IDs.
const newId = self.crypto.randomUUID().replace(/-/g, '').substring(0, 16);
await chrome.storage.local.set({ peerId: newId });
return newId;
}
@@ -1930,7 +1937,8 @@ async function handleAsyncMessage(message, sender, sendResponse) {
sendResponse({ status: 'ok' });
});
} else if (message.type === 'REGENERATE_ID') {
const newId = self.crypto.randomUUID().substring(0, 8);
// Match getPeerId()'s 16-hex-char generation — see comment there.
const newId = self.crypto.randomUUID().replace(/-/g, '').substring(0, 16);
chrome.storage.local.set({ peerId: newId }, () => {
peerId = newId;
addLog(`Identity regenerated: ${newId}`, 'success');