Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Be more tolerant of membership events in unknown rooms #8110

Merged
merged 1 commit into from
Aug 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/8110.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix a bug introduced in Synapse 1.12.0 which could cause `/sync` requests to fail with a 404 if you had a very old outstanding room invite.
2 changes: 2 additions & 0 deletions synapse/events/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ def is_out_of_band_membership(self) -> bool:
rejection. This is needed as those events are marked as outliers, but
they still need to be processed as if they're new events (e.g. updating
invite state in the database, relaying to clients, etc).

(Added in synapse 0.99.0, so may be unreliable for events received before that)
"""
return self._dict.get("out_of_band_membership", False)

Expand Down
31 changes: 25 additions & 6 deletions synapse/storage/databases/main/events_worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -586,19 +586,38 @@ def _get_events_from_db(self, event_ids, allow_rejected=False):
room_version_id = row["room_version_id"]

if not room_version_id:
# this should only happen for out-of-band membership events
if not internal_metadata.get("out_of_band_membership"):
logger.warning(
"Room %s for event %s is unknown", d["room_id"], event_id
# this should only happen for out-of-band membership events which
# arrived before #6983 landed. For all other events, we should have
# an entry in the 'rooms' table.
#
# However, the 'out_of_band_membership' flag is unreliable for older
# invites, so just accept it for all membership events.
#
if d["type"] != EventTypes.Member:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be sorely tempted to do this just for invites (and leaves?). Do we also want to assert that they are outliers?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be sorely tempted to do this just for invites (and leaves?)

considered that, but it would mean going fishing in the depths of the event dict, which felt slightly excessive. Could do it though.

Do we also want to assert that they are outliers?

possibly. it's worth noting that out-of-band invite rejections weren't flagged as outliers until 0.99.0, which I think could be problematic too, though I guess they are less likely to get loaded in a /sync, so... 🤷‍♂️

Copy link
Member

@erikjohnston erikjohnston Aug 20, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough. I'd lean on being strict where we know it is fine, but I would definitely not describe my feelings on this as "strong", so 🤷

raise Exception(
"Room %s for event %s is unknown" % (d["room_id"], event_id)
)
continue

# take a wild stab at the room version based on the event format
# so, assuming this is an out-of-band-invite that arrived before #6983
# landed, we know that the room version must be v5 or earlier (because
# v6 hadn't been invented at that point, so invites from such rooms
# would have been rejected.)
#
# The main reason we need to know the room version here (other than
# choosing the right python Event class) is in case the event later has
# to be redacted - and all the room versions up to v5 used the same
# redaction algorithm.
#
# So, the following approximations should be adequate.

if format_version == EventFormatVersions.V1:
# if it's event format v1 then it must be room v1 or v2
room_version = RoomVersions.V1
elif format_version == EventFormatVersions.V2:
# if it's event format v2 then it must be room v3
room_version = RoomVersions.V3
else:
# if it's event format v3 then it must be room v4 or v5
room_version = RoomVersions.V5
else:
room_version = KNOWN_ROOM_VERSIONS.get(room_version_id)
Expand Down