Add tombstone_successor_room_id column

This commit is contained in:
Eric Eastwood 2024-08-21 18:21:44 -05:00
parent c612572d12
commit cda2311520
4 changed files with 85 additions and 20 deletions

View file

@ -245,6 +245,8 @@ class EventContentFields:
# `m.room.encryption`` algorithm field # `m.room.encryption`` algorithm field
ENCRYPTION_ALGORITHM: Final = "algorithm" ENCRYPTION_ALGORITHM: Final = "algorithm"
TOMBSTONE_SUCCESSOR_ROOM: Final = "replacement_room"
class EventUnsignedContentFields: class EventUnsignedContentFields:
"""Fields found inside the 'unsigned' data on events""" """Fields found inside the 'unsigned' data on events"""

View file

@ -97,14 +97,16 @@ event_counter = Counter(
# State event type/key pairs that we need to gather to fill in the # State event type/key pairs that we need to gather to fill in the
# `sliding_sync_joined_rooms`/`sliding_sync_membership_snapshots` tables. # `sliding_sync_joined_rooms`/`sliding_sync_membership_snapshots` tables.
SLIDING_SYNC_RELEVANT_STATE_SET = { SLIDING_SYNC_RELEVANT_STATE_SET = (
# So we can fill in the `room_type` column in the `sliding_sync_joined_rooms` table # So we can fill in the `room_type` column
(EventTypes.Create, ""), (EventTypes.Create, ""),
# So we can fill in the `is_encrypted` column in the `sliding_sync_joined_rooms` table # So we can fill in the `is_encrypted` column
(EventTypes.RoomEncryption, ""), (EventTypes.RoomEncryption, ""),
# So we can fill in the `room_name` column in the `sliding_sync_joined_rooms` table # So we can fill in the `room_name` column
(EventTypes.Name, ""), (EventTypes.Name, ""),
} # So we can fill in the `tombstone_successor_room_id` column
(EventTypes.Tombstone, ""),
)
@attr.s(slots=True, auto_attribs=True) @attr.s(slots=True, auto_attribs=True)
@ -1877,11 +1879,22 @@ class PersistEventsStore:
# Scrutinize JSON values # Scrutinize JSON values
if room_name is None or isinstance(room_name, str): if room_name is None or isinstance(room_name, str):
sliding_sync_insert_map["room_name"] = room_name sliding_sync_insert_map["room_name"] = room_name
elif state_key == (EventTypes.Tombstone, ""):
successor_room_id = event.content.get(
EventContentFields.TOMBSTONE_SUCCESSOR_ROOM
)
# Scrutinize JSON values
if successor_room_id is None or isinstance(successor_room_id, str):
sliding_sync_insert_map["tombstone_successor_room_id"] = (
successor_room_id
)
else: else:
# We only expect to see events according to the # We only expect to see events according to the
# `SLIDING_SYNC_RELEVANT_STATE_SET`. # `SLIDING_SYNC_RELEVANT_STATE_SET`.
raise AssertionError( raise AssertionError(
f"Unexpected event (we should not be fetching extra events): {state_key} {event.event_id}" "Unexpected event (we should not be fetching extra events or this "
+ "piece of code needs to be updated to handle a new event type added "
+ "to `SLIDING_SYNC_RELEVANT_STATE_SET`): {state_key} {event.event_id}"
) )
return sliding_sync_insert_map return sliding_sync_insert_map
@ -1923,6 +1936,8 @@ class PersistEventsStore:
if create_stripped_event is not None: if create_stripped_event is not None:
sliding_sync_insert_map["has_known_state"] = True sliding_sync_insert_map["has_known_state"] = True
# XXX: Keep this up-to-date with `SLIDING_SYNC_RELEVANT_STATE_SET`
# Find the room_type # Find the room_type
sliding_sync_insert_map["room_type"] = ( sliding_sync_insert_map["room_type"] = (
create_stripped_event.content.get(EventContentFields.ROOM_TYPE) create_stripped_event.content.get(EventContentFields.ROOM_TYPE)
@ -1951,6 +1966,20 @@ class PersistEventsStore:
else None else None
) )
# Find the tombstone_successor_room_id
# Note: This isn't one of the stripped state events according to the spec
# but seems like there is no reason not to support this kind of thing.
tombstone_stripped_event = stripped_state_map.get(
(EventTypes.Tombstone, "")
)
sliding_sync_insert_map["tombstone_successor_room_id"] = (
tombstone_stripped_event.content.get(
EventContentFields.TOMBSTONE_SUCCESSOR_ROOM
)
if tombstone_stripped_event is not None
else None
)
else: else:
# No strip state provided # No strip state provided
sliding_sync_insert_map["has_known_state"] = False sliding_sync_insert_map["has_known_state"] = False

View file

@ -27,16 +27,32 @@ CREATE TABLE IF NOT EXISTS sliding_sync_joined_rooms(
-- The `stream_ordering` of the last event according to the `bump_event_types` -- The `stream_ordering` of the last event according to the `bump_event_types`
bump_stamp BIGINT, bump_stamp BIGINT,
-- `m.room.create` -> `content.type` (current state) -- `m.room.create` -> `content.type` (current state)
--
-- Useful for the `spaces`/`not_spaces` filter in the Sliding Sync API
room_type TEXT, room_type TEXT,
-- `m.room.name` -> `content.name` (current state) -- `m.room.name` -> `content.name` (current state)
--
-- Useful for the room meta data and `room_name_like` filter in the Sliding Sync API
room_name TEXT, room_name TEXT,
-- `m.room.encryption` -> `content.algorithm` (current state) -- `m.room.encryption` -> `content.algorithm` (current state)
--
-- Useful for the `is_encrypted` filter in the Sliding Sync API
is_encrypted BOOLEAN DEFAULT FALSE NOT NULL, is_encrypted BOOLEAN DEFAULT FALSE NOT NULL,
-- FIXME: Maybe we want to add `tombstone_successor_room_id` here to help with `include_old_rooms` -- `m.room.tombstone` -> `content.replacement_room` (according to the current state at the
-- (tracked by https://github.com/element-hq/synapse/issues/17540) -- time of the membership).
--
-- Useful for the `include_old_rooms` functionality in the Sliding Sync API
tombstone_successor_room_id TEXT,
PRIMARY KEY (room_id) PRIMARY KEY (room_id)
); );
-- So we can purge rooms easily.
--
-- The primary key is already `room_id`
-- So we can sort by `stream_ordering
CREATE UNIQUE INDEX IF NOT EXISTS sliding_sync_joined_rooms_event_stream_ordering ON sliding_sync_joined_rooms(event_stream_ordering);
-- A table for storing a snapshot of room meta data (historical current state relevant -- A table for storing a snapshot of room meta data (historical current state relevant
-- for sliding sync) at the time of a local user's membership. Only has rows for the -- for sliding sync) at the time of a local user's membership. Only has rows for the
-- latest membership event for a given local user in a room which matches -- latest membership event for a given local user in a room which matches
@ -72,16 +88,25 @@ CREATE TABLE IF NOT EXISTS sliding_sync_membership_snapshots(
-- no stripped state was provided for a remote invite/knock (False). -- no stripped state was provided for a remote invite/knock (False).
has_known_state BOOLEAN DEFAULT FALSE NOT NULL, has_known_state BOOLEAN DEFAULT FALSE NOT NULL,
-- `m.room.create` -> `content.type` (according to the current state at the time of -- `m.room.create` -> `content.type` (according to the current state at the time of
-- the membership) -- the membership).
--
-- Useful for the `spaces`/`not_spaces` filter in the Sliding Sync API
room_type TEXT, room_type TEXT,
-- `m.room.name` -> `content.name` (according to the current state at the time of -- `m.room.name` -> `content.name` (according to the current state at the time of
-- the membership) -- the membership).
--
-- Useful for the room meta data and `room_name_like` filter in the Sliding Sync API
room_name TEXT, room_name TEXT,
-- `m.room.encryption` -> `content.algorithm` (according to the current state at the -- `m.room.encryption` -> `content.algorithm` (according to the current state at the
-- time of the membership) -- time of the membership).
--
-- Useful for the `is_encrypted` filter in the Sliding Sync API
is_encrypted BOOLEAN DEFAULT FALSE NOT NULL, is_encrypted BOOLEAN DEFAULT FALSE NOT NULL,
-- FIXME: Maybe we want to add `tombstone_successor_room_id` here to help with `include_old_rooms` -- `m.room.tombstone` -> `content.replacement_room` (according to the current state at the
-- (tracked by https://github.com/element-hq/synapse/issues/17540) -- time of the membership).
--
-- Useful for the `include_old_rooms` functionality in the Sliding Sync API
tombstone_successor_room_id TEXT,
PRIMARY KEY (room_id, user_id) PRIMARY KEY (room_id, user_id)
); );

View file

@ -506,12 +506,14 @@ class _SlidingSyncJoinedRoomResult:
room_type: Optional[str] room_type: Optional[str]
room_name: Optional[str] room_name: Optional[str]
is_encrypted: bool is_encrypted: bool
tombstone_successor_room_id: Optional[str]
@attr.s(slots=True, frozen=True, auto_attribs=True) @attr.s(slots=True, frozen=True, auto_attribs=True)
class _SlidingSyncMembershipSnapshotResult: class _SlidingSyncMembershipSnapshotResult:
room_id: str room_id: str
user_id: str user_id: str
sender: str
membership_event_id: str membership_event_id: str
membership: str membership: str
# `event_stream_ordering` is only optional to allow easier semantics when we make # `event_stream_ordering` is only optional to allow easier semantics when we make
@ -524,6 +526,7 @@ class _SlidingSyncMembershipSnapshotResult:
room_type: Optional[str] room_type: Optional[str]
room_name: Optional[str] room_name: Optional[str]
is_encrypted: bool is_encrypted: bool
tombstone_successor_room_id: Optional[str]
class SlidingSyncPrePopulatedTablesTestCase(HomeserverTestCase): class SlidingSyncPrePopulatedTablesTestCase(HomeserverTestCase):
@ -566,6 +569,7 @@ class SlidingSyncPrePopulatedTablesTestCase(HomeserverTestCase):
"room_type", "room_type",
"room_name", "room_name",
"is_encrypted", "is_encrypted",
"tombstone_successor_room_id",
), ),
), ),
), ),
@ -579,6 +583,7 @@ class SlidingSyncPrePopulatedTablesTestCase(HomeserverTestCase):
room_type=row[3], room_type=row[3],
room_name=row[4], room_name=row[4],
is_encrypted=bool(row[5]), is_encrypted=bool(row[5]),
tombstone_successor_room_id=row[6],
) )
for row in rows for row in rows
} }
@ -601,6 +606,7 @@ class SlidingSyncPrePopulatedTablesTestCase(HomeserverTestCase):
retcols=( retcols=(
"room_id", "room_id",
"user_id", "user_id",
"sender",
"membership_event_id", "membership_event_id",
"membership", "membership",
"event_stream_ordering", "event_stream_ordering",
@ -608,6 +614,7 @@ class SlidingSyncPrePopulatedTablesTestCase(HomeserverTestCase):
"room_type", "room_type",
"room_name", "room_name",
"is_encrypted", "is_encrypted",
"tombstone_successor_room_id",
), ),
), ),
), ),
@ -617,13 +624,15 @@ class SlidingSyncPrePopulatedTablesTestCase(HomeserverTestCase):
(row[0], row[1]): _SlidingSyncMembershipSnapshotResult( (row[0], row[1]): _SlidingSyncMembershipSnapshotResult(
room_id=row[0], room_id=row[0],
user_id=row[1], user_id=row[1],
membership_event_id=row[2], sender=row[2],
membership=row[3], membership_event_id=row[3],
event_stream_ordering=row[4], membership=row[4],
has_known_state=bool(row[5]), event_stream_ordering=row[5],
room_type=row[6], has_known_state=bool(row[6]),
room_name=row[7], room_type=row[7],
is_encrypted=bool(row[8]), room_name=row[8],
is_encrypted=bool(row[9]),
tombstone_successor_room_id=row[10],
) )
for row in rows for row in rows
} }