diff --git a/synapse/storage/databases/main/event_federation.py b/synapse/storage/databases/main/event_federation.py index bf0a578b66..a27fad509e 100644 --- a/synapse/storage/databases/main/event_federation.py +++ b/synapse/storage/databases/main/event_federation.py @@ -38,6 +38,7 @@ from synapse.api.constants import MAX_DEPTH from synapse.api.errors import StoreError from synapse.api.room_versions import EventFormatVersions, RoomVersion from synapse.events import EventBase, make_event_from_dict +from synapse.events.py_protocol import MSC4242Event, supports_msc4242_state_dag from synapse.logging.opentracing import tag_args, trace from synapse.metrics import SERVER_NAME_LABEL from synapse.metrics.background_process_metrics import wrap_as_background_process @@ -1198,7 +1199,7 @@ class EventFederationWorkerStore( # future MSC4242 PRs. async def get_state_dag( self, room_id: str, forward_extrems: set[str] - ) -> dict[str, EventBase]: + ) -> dict[str, MSC4242Event]: """Get the current state DAG for the given room. This function is called when calculating a /send_join response. @@ -1231,7 +1232,7 @@ class EventFederationWorkerStore( event_map = await self.get_events(event_ids) # Filter the returned state events to only include ones on the paths back from the forward # extremities. - result: dict[str, EventBase] = {} + result: dict[str, MSC4242Event] = {} next_ids = forward_extrems seen: set[str] = set() while len(next_ids) > 0: @@ -1244,7 +1245,7 @@ class EventFederationWorkerStore( ev = event_map[event_id] # `prev_state_events` only exists on MSC4242 event formats, and this is only # called for state DAG rooms. - assert ev.room_version.msc4242_state_dags + assert supports_msc4242_state_dag(ev) result[event_id] = ev for prev_state_event_id in ev.prev_state_events: next_ids.add(prev_state_event_id) @@ -1252,7 +1253,7 @@ class EventFederationWorkerStore( assert len(result) > 0 # we always return the forward extremities # Assert that the create event was returned. Pick the first event (any will do) to verify # that this room version supports room IDs as hashes. - first_event: EventBase = next(iter(result.values())) + first_event: MSC4242Event = next(iter(result.values())) if first_event.room_version.msc4291_room_ids_as_hashes: create_event_id = f"${room_id[1:]}" assert create_event_id in result diff --git a/synapse/synapse_rust/events.pyi b/synapse/synapse_rust/events.pyi index 54a691f5fb..eb6876b0f1 100644 --- a/synapse/synapse_rust/events.pyi +++ b/synapse/synapse_rust/events.pyi @@ -273,14 +273,6 @@ class Event: def type(self) -> str: ... @property def unsigned(self) -> Unsigned: ... - @property - def prev_state_events(self) -> list[str]: - """The `prev_state_events` field of this event (MSC4242 state DAGs). - - Raises `AttributeError` for event formats which do not support MSC4242, so only - access this after checking the room version supports state DAGs. - """ - @property def internal_metadata(self) -> EventInternalMetadata: ... @property diff --git a/tests/storage/test_event_federation.py b/tests/storage/test_event_federation.py index 09dba6724c..021b29bb72 100644 --- a/tests/storage/test_event_federation.py +++ b/tests/storage/test_event_federation.py @@ -42,6 +42,7 @@ from synapse.api.room_versions import ( RoomVersion, ) from synapse.events import EventBase, make_event_from_dict +from synapse.events.py_protocol import MSC4242Event, supports_msc4242_state_dag from synapse.events.snapshot import EventContext from synapse.rest import admin from synapse.rest.client import login, room @@ -1527,7 +1528,7 @@ class EventFederationGetMissingEventsStateDAGTestCase( def _persist_state_dag( self, creator: str, graph: dict[str, list[str]] - ) -> tuple[str, dict[str, EventBase]]: + ) -> tuple[str, dict[str, MSC4242Event]]: """Build and persist a state DAG in its own room, as `build_state_dag` returns it.""" (room_id, graph_events) = build_state_dag(creator, graph) @@ -1563,7 +1564,7 @@ class EventFederationGetMissingEventsStateDAGTestCase( earliest: list[str], limit: int, room_id: str | None = None, - graph_events: dict[str, EventBase] | None = None, + graph_events: dict[str, MSC4242Event] | None = None, ) -> list[str]: """Run `get_missing_events_state_dag` in terms of fake event IDs, returning the fake event IDs which came back. Queries the room built in `prepare` unless told otherwise. @@ -1791,7 +1792,7 @@ class FakeEvent: def walk_state_dag( graph: dict[str, list[str]], - graph_events: dict[str, EventBase], + graph_events: dict[str, MSC4242Event], latest: list[str], earliest: list[str], limit: int, @@ -1830,7 +1831,7 @@ def walk_state_dag( def build_state_dag( creator: str, graph: dict[str, list[str]] -) -> tuple[str, dict[str, EventBase]]: +) -> tuple[str, dict[str, MSC4242Event]]: """Build an MSC4242 state DAG. Args: @@ -1845,7 +1846,7 @@ def build_state_dag( The create event is the exception: its ID is fixed by the room ID, so it does not start with its fake event ID. """ - graph_events: dict[str, EventBase] = {} # graph ID => built event + graph_events: dict[str, MSC4242Event] = {} # graph ID => built event create_event = make_event_from_dict( { "type": EventTypes.Create, @@ -1861,6 +1862,8 @@ def build_state_dag( }, RoomVersions.MSC4242v12, ) + # Narrow to an MSC4242 event, so that `prev_state_events` can be used. + assert supports_msc4242_state_dag(create_event) room_id = create_event.room_id entropy = 1 for index, graph_event_id in enumerate(graph): @@ -1906,6 +1909,7 @@ def build_state_dag( }, RoomVersions.MSC4242v12, ) + assert supports_msc4242_state_dag(graph_event) if not graph_event.event_id[1:].startswith(graph_event_id): entropy += 1 continue