WIP: Ensure create event appears in a valid section of the v2 response
This fails occasionally locally on postgres/sqlite no worker mode with: (also seen in the wild on matrix.org)
federation_room_join_test.go:682: m.room.create event is in an invalid position in the response => {
"device_lists": {
"changed": [
"@user-2:hs2",
"@user-1:hs1"
]
},
"device_one_time_keys_count": {
"signed_curve25519": 0
},
"device_unused_fallback_key_types": [],
"next_batch": "s5_3_0_1_1_1_1_2_0_2",
"org.matrix.msc2732.device_unused_fallback_key_types": [],
"presence": {
"events": [
{
"content": {
"currently_active": true,
"last_active_ago": 217,
"presence": "online"
},
"sender": "@user-1:hs1",
"type": "m.presence"
}
]
},
"rooms": {
"join": {
"!BPwVMIJhHZgejuqiXE:hs1": {
"account_data": {
"events": []
},
"ephemeral": {
"events": []
},
"state": {
"events": [
{
"content": {
"guest_access": "can_join"
},
"event_id": "$7korYoqgIvIiZjDx7-Ve4ZzIlZ3v9zX7uDOIqsbH49I",
"origin_server_ts": 1699379145170,
"sender": "@user-1:hs1",
"state_key": "",
"type": "m.room.guest_access",
"unsigned": {
"age": 816
}
},
{
"content": {
"history_visibility": "shared"
},
"event_id": "$6HQc2YUT8xvuKN4ktFOyfBM1QuXWU-r1hxEU0w5FU4c",
"origin_server_ts": 1699379145169,
"sender": "@user-1:hs1",
"state_key": "",
"type": "m.room.history_visibility",
"unsigned": {
"age": 817
}
},
{
"content": {
"join_rule": "invite"
},
"event_id": "$2t6w40Wn8xJSgU0BHrbmC7Deq9y0KlKF-hPXHhqsuc4",
"origin_server_ts": 1699379145169,
"sender": "@user-1:hs1",
"state_key": "",
"type": "m.room.join_rules",
"unsigned": {
"age": 817
}
},
{
"content": {
"ban": 50,
"events": {
"m.room.avatar": 50,
"m.room.canonical_alias": 50,
"m.room.encryption": 100,
"m.room.history_visibility": 100,
"m.room.name": 50,
"m.room.power_levels": 100,
"m.room.server_acl": 100,
"m.room.tombstone": 100
},
"events_default": 0,
"historical": 100,
"invite": 0,
"kick": 50,
"redact": 50,
"state_default": 50,
"users": {
"@user-1:hs1": 100
},
"users_default": 0
},
"event_id": "$LEsPRN6gtF82r_qsR4RoLcuGy9R-4D7dIiqDXN7UgEQ",
"origin_server_ts": 1699379145165,
"sender": "@user-1:hs1",
"state_key": "",
"type": "m.room.power_levels",
"unsigned": {
"age": 821
}
}
]
},
"summary": {},
"timeline": {
"events": [
{
"content": {
"creator": "@user-1:hs1",
"room_version": "10"
},
"event_id": "$OBt3NDgimNbtITAKAOrRYEhSY5uwpykCFNS6tBorVy4",
"origin_server_ts": 1699379145110,
"sender": "@user-1:hs1",
"state_key": "",
"type": "m.room.create",
"unsigned": {
"age": 876
}
},
{
"content": {
"displayname": "user-1",
"membership": "join"
},
"event_id": "$is1f6hIu79vI5Cs9OEtL6dvJikPu7fTTJXLumNDqCLM",
"origin_server_ts": 1699379145145,
"sender": "@user-1:hs1",
"state_key": "@user-1:hs1",
"type": "m.room.member",
"unsigned": {
"age": 841
}
},
{
"content": {
"avatar_url": null,
"displayname": "user-2",
"membership": "join"
},
"event_id": "$BOoylaWCMbAw1SYkL2TC0LuSQ7EVkni_1Pe11GBuI5I",
"origin_server_ts": 1699379145954,
"sender": "@user-2:hs2",
"state_key": "@user-2:hs2",
"type": "m.room.member",
"unsigned": {
"age": 2,
"prev_content": {
"displayname": "user-2",
"membership": "invite"
},
"prev_sender": "@user-1:hs1",
"replaces_state": "$o16n7D2VKzt6TVjJtcekseD5wub5Ijdw2J3zpdj4f_4"
}
}
],
"limited": true,
"prev_batch": "s5_3_0_1_1_1_1_2_0_2"
},
"unread_notifications": {
"highlight_count": 0,
"notification_count": 0
}
}
}
}
}
To spell this out, the spec says that state is
Updates to the state, between the time indicated by the since parameter, and the start of the timeline (or all state up to the start of the timeline, if since is not given, or full_state is true).
This means that the state block is a subset of the room state before the first timeline entry.
This is the first event in a room and cannot be changed. It acts as the root of all other events.
This means that the state before the create event is empty.
The invariant to enforce is thus
If m.room.create appears in a
timelineblock, it must be the first entry in the timeline and there must be nostateblock.
... so I agree with https://github.com/matrix-org/complement/pull/690/files#diff-1d4586d8fb593a2139a64386f33a3ad90c45f93281f98cc34cf0217e38522cb2R667-R674
Clearing review flags since this is a draft? Shout if that was the wrong thing to do and you wanted some sort of initial review.