diff options
author | Erik Johnston <erik@matrix.org> | 2022-07-15 12:06:41 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-15 11:06:41 +0000 |
commit | 7be954f59b4a8c98752e72c628c853d448b746ad (patch) | |
tree | 5e662c66a4b0f9f36b985402ae7f48f71d2f9a7a /synapse | |
parent | Docker: copy postgres from base image (#13279) (diff) | |
download | synapse-7be954f59b4a8c98752e72c628c853d448b746ad.tar.xz |
Fix a bug which could lead to incorrect state (#13278)
There are two fixes here: 1. A long-standing bug where we incorrectly calculated `delta_ids`; and 2. A bug introduced in #13267 where we got current state incorrect.
Diffstat (limited to 'synapse')
-rw-r--r-- | synapse/state/__init__.py | 19 | ||||
-rw-r--r-- | synapse/storage/controllers/persist_events.py | 3 |
2 files changed, 16 insertions, 6 deletions
diff --git a/synapse/state/__init__.py b/synapse/state/__init__.py index dcd272034d..3a65bd0849 100644 --- a/synapse/state/__init__.py +++ b/synapse/state/__init__.py @@ -83,7 +83,7 @@ def _gen_state_id() -> str: class _StateCacheEntry: - __slots__ = ["state", "state_group", "prev_group", "delta_ids"] + __slots__ = ["_state", "state_group", "prev_group", "delta_ids"] def __init__( self, @@ -96,7 +96,10 @@ class _StateCacheEntry: raise Exception("Either state or state group must be not None") # A map from (type, state_key) to event_id. - self.state = frozendict(state) if state is not None else None + # + # This can be None if we have a `state_group` (as then we can fetch the + # state from the DB.) + self._state = frozendict(state) if state is not None else None # the ID of a state group if one and only one is involved. # otherwise, None otherwise? @@ -114,8 +117,8 @@ class _StateCacheEntry: looking up the state group in the DB. """ - if self.state is not None: - return self.state + if self._state is not None: + return self._state assert self.state_group is not None @@ -128,7 +131,7 @@ class _StateCacheEntry: # cache eviction purposes. This is why if `self.state` is None it's fine # to return 1. - return len(self.state) if self.state else 1 + return len(self._state) if self._state else 1 class StateHandler: @@ -743,6 +746,12 @@ def _make_state_cache_entry( delta_ids: Optional[StateMap[str]] = None for old_group, old_state in state_groups_ids.items(): + if old_state.keys() - new_state.keys(): + # Currently we don't support deltas that remove keys from the state + # map, so we have to ignore this group as a candidate to base the + # new group on. + continue + n_delta_ids = {k: v for k, v in new_state.items() if old_state.get(k) != v} if not delta_ids or len(n_delta_ids) < len(delta_ids): prev_group = old_group diff --git a/synapse/storage/controllers/persist_events.py b/synapse/storage/controllers/persist_events.py index af65e5913b..cf98b0ab48 100644 --- a/synapse/storage/controllers/persist_events.py +++ b/synapse/storage/controllers/persist_events.py @@ -948,7 +948,8 @@ class EventsPersistenceStorageController: events_context, ) - return res.state, None, new_latest_event_ids + full_state = await res.get_state(self._state_controller) + return full_state, None, new_latest_event_ids async def _prune_extremities( self, |