Skip to content

Commit 08e1b63

Browse files
authored
Fix v12 rooms when using frozen dicts (#19235)
Fix #19233 Synapse fails to handle events in v12 rooms when the server is run with the `{use_frozen_dicts: True}` config. This PR fixes the issue, and adds tests which cover room creation, joining, and joining over federation, with both frozen and not frozen config settings, by extending the existing `test_send_join` federation tests. This approach to testing was chosen as it is a simple way to get high level integration style test coverage, without going through all our existing tests and trying to retroactively add in coverage when using frozen dicts. This should provide an easy place for future room versions to extend the suite of tests and reduce the chance of introducing subtle bugs like this in the future. ### Pull Request Checklist <!-- Please read https://element-hq.github.io/synapse/latest/development/contributing_guide.html before submitting your pull request --> * [x] Pull request is based on the develop branch * [x] Pull request includes a [changelog file](https://element-hq.github.io/synapse/latest/development/contributing_guide.html#changelog). The entry should: - Be a short description of your change which makes sense to users. "Fixed a bug that prevented receiving messages from other servers." instead of "Moved X method from `EventStore` to `EventWorkerStore`.". - Use markdown where necessary, mostly for `code blocks`. - End with either a period (.) or an exclamation mark (!). - Start with a capital letter. - Feel free to credit yourself, by adding a sentence "Contributed by @github_username." or "Contributed by [Your Name]." to the end of the entry. * [x] [Code style](https://element-hq.github.io/synapse/latest/code_style.html) is correct (run the [linters](https://element-hq.github.io/synapse/latest/development/contributing_guide.html#run-the-linters))
1 parent afdf9af commit 08e1b63

File tree

3 files changed

+48
-11
lines changed

3 files changed

+48
-11
lines changed

changelog.d/19235.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix v12 rooms when running with `use_frozen_dicts: True`.

synapse/events/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,7 @@ def auth_event_ids(self) -> StrCollection:
548548
assert create_event_id not in self._dict["auth_events"]
549549
if self.type == EventTypes.Create and self.get_state_key() == "":
550550
return self._dict["auth_events"] # should be []
551-
return self._dict["auth_events"] + [create_event_id]
551+
return [*self._dict["auth_events"], create_event_id]
552552

553553

554554
def _event_type_from_format_version(

tests/federation/test_federation_server.py

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
from synapse.api.errors import FederationError
3131
from synapse.api.room_versions import KNOWN_ROOM_VERSIONS, RoomVersions
3232
from synapse.config.server import DEFAULT_ROOM_VERSION
33+
from synapse.crypto.event_signing import add_hashes_and_signatures
3334
from synapse.events import EventBase, make_event_from_dict
3435
from synapse.federation.federation_base import event_from_pdu_json
3536
from synapse.http.types import QueryParams
@@ -356,19 +357,44 @@ def _make_join(self, user_id: str) -> JsonDict:
356357
self.assertEqual(channel.code, HTTPStatus.OK, channel.json_body)
357358
return channel.json_body
358359

359-
def test_send_join(self) -> None:
360+
def _test_send_join_common(self, room_version: str) -> None:
360361
"""happy-path test of send_join"""
362+
creator_user_id = self.register_user(f"kermit_v{room_version}", "test")
363+
tok = self.login(f"kermit_v{room_version}", "test")
364+
room_id = self.helper.create_room_as(
365+
room_creator=creator_user_id, tok=tok, room_version=room_version
366+
)
367+
368+
# Second member joins
369+
second_member_user_id = self.register_user(f"fozzie_v{room_version}", "bear")
370+
tok2 = self.login(f"fozzie_v{room_version}", "bear")
371+
self.helper.join(room_id, second_member_user_id, tok=tok2)
372+
373+
# Make join for remote user
361374
joining_user = "@misspiggy:" + self.OTHER_SERVER_NAME
362-
join_result = self._make_join(joining_user)
375+
channel = self.make_signed_federation_request(
376+
"GET",
377+
f"/_matrix/federation/v1/make_join/{room_id}/{joining_user}?ver={room_version}",
378+
)
379+
self.assertEqual(channel.code, HTTPStatus.OK, channel.json_body)
380+
join_result = channel.json_body
363381

382+
# Sign and send the join
364383
join_event_dict = join_result["event"]
365384
self.add_hashes_and_signatures_from_other_server(
366385
join_event_dict,
367-
KNOWN_ROOM_VERSIONS[DEFAULT_ROOM_VERSION],
386+
KNOWN_ROOM_VERSIONS[room_version],
368387
)
388+
if room_version in ["1", "2"]:
389+
add_hashes_and_signatures(
390+
KNOWN_ROOM_VERSIONS[room_version],
391+
join_event_dict,
392+
signature_name=self.hs.hostname,
393+
signing_key=self.hs.signing_key,
394+
)
369395
channel = self.make_signed_federation_request(
370396
"PUT",
371-
f"/_matrix/federation/v2/send_join/{self._room_id}/x",
397+
f"/_matrix/federation/v2/send_join/{room_id}/x",
372398
content=join_event_dict,
373399
)
374400
self.assertEqual(channel.code, HTTPStatus.OK, channel.json_body)
@@ -384,8 +410,8 @@ def test_send_join(self) -> None:
384410
("m.room.power_levels", ""),
385411
("m.room.join_rules", ""),
386412
("m.room.history_visibility", ""),
387-
("m.room.member", "@kermit:test"),
388-
("m.room.member", "@fozzie:test"),
413+
("m.room.member", f"@kermit_v{room_version}:test"),
414+
("m.room.member", f"@fozzie_v{room_version}:test"),
389415
# nb: *not* the joining user
390416
],
391417
)
@@ -398,18 +424,28 @@ def test_send_join(self) -> None:
398424
returned_auth_chain_events,
399425
[
400426
("m.room.create", ""),
401-
("m.room.member", "@kermit:test"),
427+
("m.room.member", f"@kermit_v{room_version}:test"),
402428
("m.room.power_levels", ""),
403429
("m.room.join_rules", ""),
404430
],
405431
)
406432

407433
# the room should show that the new user is a member
408-
r = self.get_success(
409-
self._storage_controllers.state.get_current_state(self._room_id)
410-
)
434+
r = self.get_success(self._storage_controllers.state.get_current_state(room_id))
411435
self.assertEqual(r[("m.room.member", joining_user)].membership, "join")
412436

437+
@parameterized.expand([(k,) for k in KNOWN_ROOM_VERSIONS.keys()])
438+
@override_config({"use_frozen_dicts": True})
439+
def test_send_join_with_frozen_dicts(self, room_version: str) -> None:
440+
"""Test send_join with USE_FROZEN_DICTS=True"""
441+
self._test_send_join_common(room_version)
442+
443+
@parameterized.expand([(k,) for k in KNOWN_ROOM_VERSIONS.keys()])
444+
@override_config({"use_frozen_dicts": False})
445+
def test_send_join_without_frozen_dicts(self, room_version: str) -> None:
446+
"""Test send_join with USE_FROZEN_DICTS=False"""
447+
self._test_send_join_common(room_version)
448+
413449
def test_send_join_partial_state(self) -> None:
414450
"""/send_join should return partial state, if requested"""
415451
joining_user = "@misspiggy:" + self.OTHER_SERVER_NAME

0 commit comments

Comments
 (0)