fix(voice): wait for key rotation via nio sync, not HTTP fetch
io.element.call.encryption_keys events are Megolm-encrypted in this room (appear as m.room.encrypted). The HTTP fetch cannot decrypt them — only the nio sync client can via Olm/Megolm decryption. Change the post-connect rotation poll to check self._caller_all_keys directly (updated by on_encryption_key() via nio sync) instead of calling _fetch_encryption_key_http() which always returns nothing in encrypted rooms. Also extends wait to 10s and adds progress logging every 2s. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
15
voice.py
15
voice.py
@@ -258,22 +258,23 @@ class VoiceSession:
|
||||
len(self.lk_room.remote_participants))
|
||||
|
||||
# Element Call rotates its encryption key when bot joins the LiveKit room.
|
||||
# We fetched the pre-join key above; now wait for EC to generate and publish
|
||||
# the post-join rotated key via Matrix timeline.
|
||||
# EC sends the new key via Matrix (Megolm-encrypted); nio sync will decrypt it
|
||||
# and call on_encryption_key(), which updates self._caller_all_keys.
|
||||
# NOTE: HTTP fetch is useless here — keys are Matrix-E2EE encrypted (m.room.encrypted).
|
||||
pre_max_idx = max(self._caller_all_keys.keys()) if self._caller_all_keys else -1
|
||||
logger.info("Polling for EC key rotation (pre-join max_idx=%d)...", pre_max_idx)
|
||||
for _attempt in range(10): # poll up to 5s (10 × 0.5s)
|
||||
logger.info("Waiting for EC key rotation via nio sync (current max_idx=%d)...", pre_max_idx)
|
||||
for _attempt in range(20): # up to 10s (20 × 0.5s)
|
||||
await asyncio.sleep(0.5)
|
||||
await self._fetch_encryption_key_http()
|
||||
new_max = max(self._caller_all_keys.keys()) if self._caller_all_keys else -1
|
||||
if new_max > pre_max_idx:
|
||||
self._caller_key = self._caller_all_keys[new_max]
|
||||
logger.info("Key rotated: index %d→%d (%d bytes)",
|
||||
pre_max_idx, new_max, len(self._caller_key))
|
||||
break
|
||||
logger.debug("Key rotation poll %d: max_idx still %d", _attempt + 1, new_max)
|
||||
if _attempt % 4 == 3: # log every 2s
|
||||
logger.info("Key rotation wait %ds: max_idx still %d", (_attempt + 1) // 2, new_max)
|
||||
else:
|
||||
logger.warning("No key rotation after 5s — using pre-join key[%d]", pre_max_idx)
|
||||
logger.warning("No key rotation after 10s — using pre-join key[%d]", pre_max_idx)
|
||||
|
||||
# Set per-participant keys via key provider
|
||||
kp = self.lk_room.e2ee_manager.key_provider
|
||||
|
||||
Reference in New Issue
Block a user