Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
65801ac
remove room_id from default_event_fields() for msc4291 rooms(room_id …
jason-famedly May 20, 2026
850c4e2
change DEFAULT_ROOM_VERSION to "12"
jason-famedly May 15, 2026
6135671
fix storage.test_stream.GetCurrentStateDeltaMembershipChangesForUserF…
jason-famedly May 8, 2026
f607ebf
fix storage.test_stream.GetCurrentStateDeltaMembershipChangesForUserT…
jason-famedly May 11, 2026
3e42b93
fix rest.client.test_upgrade_room.UpgradeRoomTest case test for strin…
jason-famedly May 11, 2026
211eaad
fix rest.client.test_upgrade_room.UpgradeRoomTest cases for power lev…
jason-famedly May 11, 2026
2b2d78b
fix rest.client.test_rooms.MSC4293RedactOnBanKickTestCase to use defa…
jason-famedly May 8, 2026
37c3ae4
fix rest.client.test_rooms.MSC4293RedactOnBanKickTestCase to reflect …
jason-famedly May 8, 2026
f8fe546
fix rest.client.test_rooms.MSC4293RedactOnBanKickTestCase to not test…
jason-famedly May 8, 2026
73237ae
fix rest.client.test_third_party_rules.ThirdPartyRulesTestCase by rem…
jason-famedly May 11, 2026
a783a44
fix rest.client.test_sync.UnreadMessagesTestCase to handle power leve…
jason-famedly May 11, 2026
6b7a20b
fix module_api.test_api.ModuleApiTestCase by correcting assumptions
jason-famedly May 11, 2026
5e4fb99
fix storage.test_cleanup_extrems.CleanupExtremDummyEventsTestCase
jason-famedly May 11, 2026
dbac058
change rest.admin.test_room.MakeRoomAdminTestCase to use a sentinel u…
jason-famedly May 11, 2026
fb91c16
fix handlers.test_room_member.TestJoinsLimitedByPerRoomRateLimiter fo…
jason-famedly May 11, 2026
1c72d11
fix handlers.test_device.DeviceUnPartialStateTestCase to handle both …
jason-famedly May 11, 2026
4bba2ab
fix federation.test_federation_out_of_band_membership for room versio…
jason-famedly May 13, 2026
a3f1993
fix rest.client.sliding_sync.test_rooms_required_state.SlidingSyncRoo…
jason-famedly May 13, 2026
6628ef2
fix handlers.test_present.PresenceJoinTestCase by removing the creati…
jason-famedly May 14, 2026
091af8f
fix handlers.test_federation.FederationEventHandlerTests several test…
jason-famedly May 14, 2026
f3a1084
fix federation.test_federation_client.FederationClientTest to use def…
jason-famedly May 14, 2026
3e3debe
fix handlers.test_message.EventCreationTestCase for call invite creat…
jason-famedly May 15, 2026
317fe8a
pin handlers.test_register.RegistrationTestCase.test_auto_create_auto…
jason-famedly May 15, 2026
8935134
(maybe) fix handlers.test_federation_event.FederationEventHandlerTest…
jason-famedly May 15, 2026
f35b8f3
[diverted]fix MSC3912-relation-based-redaction for room versions > 10…
jason-famedly May 14, 2026
c005e96
fix handlers.test_sync.SyncTestCase.test_unknown_room_version by avoi…
jason-famedly May 14, 2026
3dfd8fe
[diverted]fix _rebuild_event_after_third_party_rules() to be creation…
jason-famedly May 7, 2026
e408cef
[revert after #19723] maybe fix for rest.client.sliding_sync/test_roo…
jason-famedly May 15, 2026
5ba81ad
Add in new helper to `BaseMultiWorkerStreamTestCase` to opportunistic…
jason-famedly Aug 19, 2026
b33f721
fix two tests that needed rooms on different workers
jason-famedly Aug 19, 2026
7e429a8
fix replication.test_federation_sender_shard.FederationSenderTestCase…
jason-famedly Aug 19, 2026
3a3aa53
changelog
jason-famedly Aug 19, 2026
487be86
Copy mutable config containers in deepcopy_config
barodeur Aug 27, 2026
2f8c244
Merge branch 'develop' into jason/v12-fix-unit-tests-take-two
jason-famedly Aug 28, 2026
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/20130.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Raise default room version to "12". Contributed by @jason-famedly @famedly.
2 changes: 1 addition & 1 deletion synapse/config/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ def generate_ip_set(
"fec0::/10",
]

DEFAULT_ROOM_VERSION = "11"
DEFAULT_ROOM_VERSION = "12"

# Defaults for the presence state machine timers, in milliseconds. Overridden
# by the corresponding options in the `presence` config section.
Expand Down
27 changes: 22 additions & 5 deletions synapse/handlers/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -2404,7 +2404,15 @@ async def _rebuild_event_after_third_party_rules(
original_event.room_version, third_party_result
)
self.validator.validate_builder(builder)
assert builder.room_id is not None

# The room_id should only be None for creation events using msc4291
# rooms(version "12" and newer)
if not (
builder.room_version.msc4291_room_ids_as_hashes
and builder.type == EventTypes.Create
):
assert builder.room_id is not None

except SynapseError as e:
raise Exception(
"Third party rules module created an invalid event: " + e.msg,
Expand Down Expand Up @@ -2439,12 +2447,21 @@ async def _rebuild_event_after_third_party_rules(
for k, v in original_event.internal_metadata.get_dict().items():
setattr(builder.internal_metadata, k, v)

# modules can send new state events, so we re-calculate the auth events just in
# case.
prev_event_ids = await self.store.get_prev_events_for_room(builder.room_id)
# Creation events using msc4291 rooms will not have a room_id, and will
# also not have prev_events nor prev_state_events.
# This was asserted above, so makes an acceptable sign that room_id can not be
# None here(which makes mypy happy) but if it is then the lists should be empty.
prev_event_ids = []
if builder.room_id is not None:
# modules can send new state events, so we re-calculate the auth events just
# in case.
prev_event_ids = await self.store.get_prev_events_for_room(builder.room_id)

prev_state_events = None
if original_event.room_version.msc4242_state_dags:
if (
original_event.room_version.msc4242_state_dags
and builder.room_id is not None
):
prev_state_events = list(
await self.store.get_state_dag_extremities(builder.room_id)
)
Expand Down
26 changes: 19 additions & 7 deletions synapse/handlers/relations.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
BundledAggregations,
ThreadAggregation,
)
from synapse.synapse_rust.room_versions import RoomVersion
from synapse.types import JsonDict, Requester, UserID
from synapse.util.async_helpers import gather_results
from synapse.visibility import filter_and_transform_events_for_client
Expand Down Expand Up @@ -193,6 +194,7 @@ async def redact_events_related_to(
event_id: str,
initial_redaction_event: EventBase,
relation_types: list[str],
room_version: RoomVersion,
) -> None:
"""Redacts all events related to the given event ID with one of the given
relation types.
Expand All @@ -210,6 +212,8 @@ async def redact_events_related_to(
event_id.
relation_types: The types of relations to look for. If "*" is in the list,
all related events will be redacted regardless of the type.
room_version: The RoomVersion of the room, for deciding where the 'redacts'
key should go in the event dict

Raises:
ShadowBanError if the requester is shadow-banned
Expand All @@ -226,16 +230,24 @@ async def redact_events_related_to(
)

for related_event_id in related_event_ids:
# Depending on the room version involved, the "redacts" key can go in one of
# two places. If we only use what was provided in the initial event, it will
# only target an event that was already redacted and nothing will happen.
new_redaction_content = dict(initial_redaction_event.content)
event_dict: JsonDict = {
"type": EventTypes.Redaction,
"content": new_redaction_content,
"room_id": initial_redaction_event.room_id,
"sender": requester.user.to_string(),
}
if room_version.updated_redaction_rules:
event_dict["content"].update({"redacts": related_event_id})
else:
event_dict["redacts"] = related_event_id
try:
await self._event_creation_handler.create_and_send_nonmember_event(
requester,
{
"type": EventTypes.Redaction,
"content": initial_redaction_event.content,
"room_id": initial_redaction_event.room_id,
"sender": requester.user.to_string(),
"redacts": related_event_id,
},
event_dict,
ratelimit=False,
)
except SynapseError as e:
Expand Down
1 change: 1 addition & 0 deletions synapse/rest/client/room.py
Original file line number Diff line number Diff line change
Expand Up @@ -1412,6 +1412,7 @@ async def _do(
event_id=event_id,
initial_redaction_event=event,
relation_types=with_relations,
room_version=room_version,
)

event_id = event.event_id
Expand Down
8 changes: 4 additions & 4 deletions synapse/storage/databases/main/events_worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -1468,7 +1468,7 @@ async def _fetch_event_ids_and_get_outstanding_redactions(
#
if d["type"] != EventTypes.Member:
raise InvalidEventError(
"Room %s for event %s is unknown" % (d["room_id"], event_id)
"Room %s for event %s is unknown" % (d.get("room_id"), event_id)
)

# so, assuming this is an out-of-band-invite that arrived before
Expand Down Expand Up @@ -1499,7 +1499,7 @@ async def _fetch_event_ids_and_get_outstanding_redactions(
logger.warning(
"Event %s in room %s has unknown room version %s",
event_id,
d["room_id"],
d.get("room_id"),
room_version_id,
)
continue
Expand All @@ -1509,7 +1509,7 @@ async def _fetch_event_ids_and_get_outstanding_redactions(
"Event %s in room %s with version %s has wrong format: "
"expected %s, was %s",
event_id,
d["room_id"],
d.get("room_id"),
room_version_id,
room_version.event_format,
format_version,
Expand Down Expand Up @@ -1538,7 +1538,7 @@ async def _fetch_event_ids_and_get_outstanding_redactions(
# it's difficult to see what to do here. Pretty much all bets are off
# if Synapse cannot rely on the consistency of its database.
raise DatabaseCorruptionError(
d["room_id"], event_id, original_ev.event_id
d.get("room_id"), event_id, original_ev.event_id
)

event_map[event_id] = original_ev
Expand Down
74 changes: 47 additions & 27 deletions tests/federation/test_federation_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@
from twisted.internet import defer
from twisted.internet.testing import MemoryReactor

from synapse.api.room_versions import RoomVersions
from synapse.events import EventBase
from synapse.rest import admin
from synapse.rest.client import login, room
from synapse.server import HomeServer
from synapse.util.clock import Clock

from tests.test_utils import FakeResponse, event_injection
from tests.test_utils.event_builders import make_test_pdu_event
from tests.unittest import FederatingHomeserverTestCase


Expand All @@ -58,28 +58,42 @@ def prepare(
self.reactor.advance(1000000000)

self.creator = f"@creator:{self.OTHER_SERVER_NAME}"
self.test_room_id = "!room_id"
self.room_version = self.hs.config.server.default_room_version

def test_get_room_state(self) -> None:
# mock up some events to use in the response.
# In real life, these would have things in `prev_events` and `auth_events`, but that's
# a bit annoying to mock up, and the code under test doesn't care, so we don't bother.
# In real life, these would have things in `prev_events` and `auth_events`, but
# that's a bit annoying to mock up, and the code under test doesn't care, so we
# don't bother. We do bother with the room_id though, since it has to be
# generated by the hash of the creation event.
create_event_source = {
"type": "m.room.create",
"state_key": "",
"sender": self.creator,
"content": {"room_version": self.room_version.identifier},
"prev_events": [],
"auth_events": [],
"depth": 1,
"origin_server_ts": 500,
}
if not self.room_version.msc4291_room_ids_as_hashes:
# Do not bother saving this now, we will pull it out of the calculated event
# later.
create_event_source["room_id"] = f"!room:{self.OTHER_SERVER_NAME}"

create_event_dict = self.add_hashes_and_signatures_from_other_server(
{
"room_id": self.test_room_id,
"type": "m.room.create",
"state_key": "",
"sender": self.creator,
"content": {"creator": self.creator},
"prev_events": [],
"auth_events": [],
"depth": 1,
"origin_server_ts": 500,
}
create_event_source,
self.room_version,
)
create_event = make_test_pdu_event(
create_event_source,
self.room_version,
)
room_id = create_event.room_id

member_event_dict = self.add_hashes_and_signatures_from_other_server(
{
"room_id": self.test_room_id,
"room_id": room_id,
"type": "m.room.member",
"sender": self.creator,
"state_key": self.creator,
Expand All @@ -88,11 +102,12 @@ def test_get_room_state(self) -> None:
"auth_events": [],
"depth": 2,
"origin_server_ts": 600,
}
},
self.room_version,
)
pl_event_dict = self.add_hashes_and_signatures_from_other_server(
{
"room_id": self.test_room_id,
"room_id": room_id,
"type": "m.room.power_levels",
"sender": self.creator,
"state_key": "",
Expand All @@ -101,7 +116,8 @@ def test_get_room_state(self) -> None:
"auth_events": [],
"depth": 3,
"origin_server_ts": 700,
}
},
self.room_version,
)

# mock up the response, and have the agent return it
Expand All @@ -125,16 +141,19 @@ def test_get_room_state(self) -> None:
state_resp, auth_resp = self.get_success(
self.hs.get_federation_client().get_room_state(
"yet.another.server",
self.test_room_id,
room_id,
"event_id",
RoomVersions.V9,
self.room_version,
)
)

# check the right call got made to the agent
self._mock_agent.request.assert_called_once_with(
b"GET",
b"matrix-federation://yet.another.server/_matrix/federation/v1/state/%21room_id?event_id=event_id",
# Please double-check me that ascii encoding is correct thing to do here
f"matrix-federation://yet.another.server/_matrix/federation/v1/state/%21{room_id[1:]}?event_id=event_id".encode(
"ascii"
),
headers=mock.ANY,
bodyProducer=None,
)
Expand All @@ -158,7 +177,7 @@ def test_get_pdu_returns_nothing_when_event_does_not_exist(self) -> None:
self.hs.get_federation_client().get_pdu(
["yet.another.server"],
"event_should_not_exist",
RoomVersions.V9,
self.room_version,
)
)
self.assertEqual(pulled_pdu_info, None)
Expand All @@ -185,7 +204,7 @@ def test_get_pdu_event_from_cache_is_pristine(self) -> None:
self.hs.get_federation_client().get_pdu(
["yet.another.server"],
remote_pdu.event_id,
RoomVersions.V9,
self.room_version,
)
)
assert pulled_pdu_info2 is not None
Expand All @@ -204,7 +223,7 @@ def _get_pdu_once(self) -> EventBase:
"""
message_event_dict = self.add_hashes_and_signatures_from_other_server(
{
"room_id": self.test_room_id,
"room_id": f"!bogus_made_up_room_id:{self.OTHER_SERVER_NAME}",
"type": "m.room.message",
"sender": self.creator,
"state_key": "",
Expand All @@ -213,7 +232,8 @@ def _get_pdu_once(self) -> EventBase:
"auth_events": [],
"origin_server_ts": 700,
"depth": 10,
}
},
self.room_version,
)

# mock up the response, and have the agent return it
Expand All @@ -233,7 +253,7 @@ def _get_pdu_once(self) -> EventBase:
self.hs.get_federation_client().get_pdu(
["yet.another.server"],
"event_id",
RoomVersions.V9,
self.room_version,
)
)
assert pulled_pdu_info is not None
Expand Down
15 changes: 5 additions & 10 deletions tests/federation/test_federation_out_of_band_membership.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
from twisted.internet.testing import MemoryReactor

from synapse.api.constants import EventContentFields, EventTypes, Membership
from synapse.api.room_versions import RoomVersion, RoomVersions
from synapse.api.room_versions import RoomVersion
from synapse.events import EventBase
from synapse.events.utils import strip_event
from synapse.federation.transport.client import SendJoinResponse
Expand Down Expand Up @@ -188,13 +188,11 @@ def _invite_local_user_to_remote_room_and_join(self) -> RemoteRoomJoinResult:

# Create a remote room
room_creator_user_id = f"@remote-user:{self.OTHER_SERVER_NAME}"
remote_room_id = f"!remote-room:{self.OTHER_SERVER_NAME}"
room_version = RoomVersions.V11
room_version = self.hs.config.server.default_room_version

room_create_event = make_test_event(
self.add_hashes_and_signatures_from_other_server(
{
"room_id": remote_room_id,
"sender": room_creator_user_id,
"depth": 1,
"origin_server_ts": 1,
Expand All @@ -210,6 +208,8 @@ def _invite_local_user_to_remote_room_and_join(self) -> RemoteRoomJoinResult:
room_version=room_version,
)

remote_room_id = room_create_event.room_id

creator_membership_event = make_test_event(
self.add_hashes_and_signatures_from_other_server(
{
Expand All @@ -220,7 +220,7 @@ def _invite_local_user_to_remote_room_and_join(self) -> RemoteRoomJoinResult:
"type": EventTypes.Member,
"state_key": room_creator_user_id,
"content": {"membership": Membership.JOIN},
"auth_events": [room_create_event.event_id],
"auth_events": [],
"prev_events": [room_create_event.event_id],
}
),
Expand All @@ -239,7 +239,6 @@ def _invite_local_user_to_remote_room_and_join(self) -> RemoteRoomJoinResult:
"state_key": local_user1_id,
"content": {"membership": Membership.INVITE},
"auth_events": [
room_create_event.event_id,
creator_membership_event.event_id,
],
"prev_events": [creator_membership_event.event_id],
Expand Down Expand Up @@ -300,7 +299,6 @@ def _invite_local_user_to_remote_room_and_join(self) -> RemoteRoomJoinResult:
"state_key": local_user1_id,
"content": {"membership": Membership.JOIN},
"auth_events": [
room_create_event.event_id,
user1_invite_membership_event.event_id,
],
"prev_events": [user1_invite_membership_event.event_id],
Expand Down Expand Up @@ -542,9 +540,6 @@ async def put_json(
"state_key": local_user2_id,
"content": {"membership": Membership.INVITE},
"auth_events": [
remote_room_join_result.state_map[
(EventTypes.Create, "")
].event_id,
remote_room_join_result.state_map[
(
EventTypes.Member,
Expand Down
Loading
Loading