Try calculate more

This commit is contained in:
Eric Eastwood 2024-05-08 23:50:31 -05:00
parent 10ffae6c50
commit 6bf48968eb
2 changed files with 64 additions and 17 deletions

View file

@ -289,9 +289,9 @@ class SyncResult:
class E2eeSyncResult:
next_batch: StreamToken
to_device: List[JsonDict]
# device_lists: DeviceListUpdates
# device_one_time_keys_count: JsonMapping
# device_unused_fallback_key_types: List[str]
device_lists: DeviceListUpdates
device_one_time_keys_count: JsonMapping
device_unused_fallback_key_types: List[str]
class SyncHandler:
@ -1813,19 +1813,46 @@ class SyncHandler:
full_state=False,
)
# 1. Calculate `device_lists`
device_lists = await self._generate_sync_entry_for_device_list(
sync_result_builder
)
# 2. Calculate `to_device` events
# 1. Calculate `to_device` events
await self._generate_sync_entry_for_to_device(sync_result_builder)
# 2. Calculate `device_lists`
# Device list updates are sent if a since token is provided.
device_lists = DeviceListUpdates()
include_device_list_updates = bool(since_token and since_token.device_list_key)
if include_device_list_updates:
device_lists = await self._generate_sync_entry_for_device_list(
sync_result_builder,
# TODO: Do we need to worry about these? All of this info is
# normally calculated when we `_generate_sync_entry_for_rooms()` but we
# probably don't want to do all of that work for this endpoint.
newly_joined_rooms=frozenset(),
newly_joined_or_invited_or_knocked_users=frozenset(),
newly_left_rooms=frozenset(),
newly_left_users=frozenset(),
)
# 3. Calculate `device_one_time_keys_count` and `device_unused_fallback_key_types`
device_id = sync_config.device_id
one_time_keys_count: JsonMapping = {}
unused_fallback_key_types: List[str] = []
if device_id:
# TODO: We should have a way to let clients differentiate between the states of:
# * no change in OTK count since the provided since token
# * the server has zero OTKs left for this device
# Spec issue: https://github.com/matrix-org/matrix-doc/issues/3298
one_time_keys_count = await self.store.count_e2e_one_time_keys(
user_id, device_id
)
unused_fallback_key_types = list(
await self.store.get_e2e_unused_fallback_key_types(user_id, device_id)
)
return E2eeSyncResult(
to_device=sync_result_builder.to_device,
device_lists=device_lists,
# device_one_time_keys_count: JsonMapping
# device_unused_fallback_key_types: List[str]
device_one_time_keys_count=one_time_keys_count,
device_unused_fallback_key_types=unused_fallback_key_types,
next_batch=sync_result_builder.now_token,
)
@ -2007,7 +2034,7 @@ class SyncHandler:
users_that_have_changed = set()
joined_rooms = sync_result_builder.joined_room_ids
joined_room_ids = sync_result_builder.joined_room_ids
# Step 1a, check for changes in devices of users we share a room
# with
@ -2032,14 +2059,14 @@ class SyncHandler:
# or if the changed user is the syncing user (as we always
# want to include device list updates of their own devices).
if user_id == changed_user_id or any(
rid in joined_rooms for rid in entries
rid in joined_room_ids for rid in entries
):
users_that_have_changed.add(changed_user_id)
else:
users_that_have_changed = (
await self._device_handler.get_device_changes_in_shared_rooms(
user_id,
sync_result_builder.joined_room_ids,
joined_room_ids,
from_token=since_token,
)
)
@ -2066,7 +2093,7 @@ class SyncHandler:
# Remove any users that we still share a room with.
left_users_rooms = await self.store.get_rooms_for_users(newly_left_users)
for user_id, entries in left_users_rooms.items():
if any(rid in joined_rooms for rid in entries):
if any(rid in joined_room_ids for rid in entries):
newly_left_users.discard(user_id)
return DeviceListUpdates(changed=users_that_have_changed, left=newly_left_users)

View file

@ -624,9 +624,11 @@ class SlidingSyncE2eeRestServlet(RestServlet):
if since is not None:
since_token = await StreamToken.from_string(self.store, since)
logger.info(f"sync with since_token: {since_token}")
# Request cache key
request_key = (
SyncVersion.SYNC_V2,
SyncVersion.E2EE_SYNC,
user,
timeout,
since,
@ -636,7 +638,7 @@ class SlidingSyncE2eeRestServlet(RestServlet):
sync_result = await self.sync_handler.wait_for_sync_for_user(
requester,
sync_config,
SyncVersion.SYNC_V2,
SyncVersion.E2EE_SYNC,
request_key,
since_token=since_token,
timeout=timeout,
@ -655,6 +657,24 @@ class SlidingSyncE2eeRestServlet(RestServlet):
if sync_result.to_device:
response["to_device"] = {"events": sync_result.to_device}
if sync_result.device_lists.changed:
response["device_lists"]["changed"] = list(sync_result.device_lists.changed)
if sync_result.device_lists.left:
response["device_lists"]["left"] = list(sync_result.device_lists.left)
# We always include this because https://github.com/vector-im/element-android/issues/3725
# The spec isn't terribly clear on when this can be omitted and how a client would tell
# the difference between "no keys present" and "nothing changed" in terms of whole field
# absent / individual key type entry absent
# Corresponding synapse issue: https://github.com/matrix-org/synapse/issues/10456
response["device_one_time_keys_count"] = sync_result.device_one_time_keys_count
# https://github.com/matrix-org/matrix-doc/blob/54255851f642f84a4f1aaf7bc063eebe3d76752b/proposals/2732-olm-fallback-keys.md
# states that this field should always be included, as long as the server supports the feature.
response["device_unused_fallback_key_types"] = (
sync_result.device_unused_fallback_key_types
)
return 200, response