summary refs log tree commit diff
path: root/synapse
diff options
context:
space:
mode:
authorRichard van der Hoff <1389908+richvdh@users.noreply.github.com>2024-04-04 13:14:24 +0100
committerGitHub <noreply@github.com>2024-04-04 12:14:24 +0000
commit230b709d9d8b09fd4884be1265db535263975e35 (patch)
tree4bd3b7440a246585f1f340dec8cf35a8a77c4d63 /synapse
parentFix bug in `/sync` response for archived rooms (#16932) (diff)
downloadsynapse-230b709d9d8b09fd4884be1265db535263975e35.tar.xz
`/sync`: fix bug in calculating `state` response (#16930)
Fix a long-standing issue which could cause state to be omitted from the
sync response if the last event was filtered out.

Fixes: https://github.com/element-hq/synapse/issues/16928
Diffstat (limited to 'synapse')
-rw-r--r--synapse/handlers/sync.py54
1 files changed, 13 insertions, 41 deletions
diff --git a/synapse/handlers/sync.py b/synapse/handlers/sync.py
index 7fcd54ac55..773e291aa8 100644
--- a/synapse/handlers/sync.py
+++ b/synapse/handlers/sync.py
@@ -1187,15 +1187,14 @@ class SyncHandler:
             await_full_state = True
             lazy_load_members = False
 
-        if batch:
-            state_at_timeline_end = (
-                await self._state_storage_controller.get_state_ids_for_event(
-                    batch.events[-1].event_id,
-                    state_filter=state_filter,
-                    await_full_state=await_full_state,
-                )
-            )
+        state_at_timeline_end = await self.get_state_at(
+            room_id,
+            stream_position=end_token,
+            state_filter=state_filter,
+            await_full_state=await_full_state,
+        )
 
+        if batch:
             state_at_timeline_start = (
                 await self._state_storage_controller.get_state_ids_for_event(
                     batch.events[0].event_id,
@@ -1204,13 +1203,6 @@ class SyncHandler:
                 )
             )
         else:
-            state_at_timeline_end = await self.get_state_at(
-                room_id,
-                stream_position=end_token,
-                state_filter=state_filter,
-                await_full_state=await_full_state,
-            )
-
             state_at_timeline_start = state_at_timeline_end
 
         state_ids = _calculate_state(
@@ -1305,23 +1297,12 @@ class SyncHandler:
                 await_full_state=await_full_state,
             )
 
-            if batch:
-                state_at_timeline_end = (
-                    await self._state_storage_controller.get_state_ids_for_event(
-                        batch.events[-1].event_id,
-                        state_filter=state_filter,
-                        await_full_state=await_full_state,
-                    )
-                )
-            else:
-                # We can get here if the user has ignored the senders of all
-                # the recent events.
-                state_at_timeline_end = await self.get_state_at(
-                    room_id,
-                    stream_position=end_token,
-                    state_filter=state_filter,
-                    await_full_state=await_full_state,
-                )
+            state_at_timeline_end = await self.get_state_at(
+                room_id,
+                stream_position=end_token,
+                state_filter=state_filter,
+                await_full_state=await_full_state,
+            )
 
             state_ids = _calculate_state(
                 timeline_contains=timeline_state,
@@ -2847,15 +2828,6 @@ def _calculate_state(
     # timeline. We have no way to represent that in the /sync response, and we don't
     # even try; it is ether omitted or plonked into `state` as if it were at the start
     # of the timeline, depending on what else is in the timeline.)
-    #
-    # ----------
-    #
-    # Aside 2: it's worth noting that `timeline_end`, as provided to us, is actually
-    # the state *before* the final event in the timeline. In other words: if the final
-    # event in the timeline is a state event, it won't be included in `timeline_end`.
-    # However, that doesn't matter here, because the only difference can be in that
-    # one piece of state, and by definition that event is in the timeline, so we
-    # don't need to include it in the `state` section.
 
     state_ids = (
         (timeline_end_ids | timeline_start_ids)