浏览代码

Ensure `(room_id, next_batch_id)` is unique to avoid cross-talk/conflicts between batches (MSC2716) (#10877)

Part of [MSC2716](https://github.com/matrix-org/matrix-doc/pull/2716)

Part of https://github.com/matrix-org/synapse/issues/10737
tags/v1.45.0rc1
Eric Eastwood 2 年前
committed by GitHub
父节点
当前提交
9fd057b8c5
找不到此签名对应的密钥 GPG 密钥 ID: 4AEE18F83AFDEB23
共有 4 个文件被更改,包括 43 次插入4 次删除
  1. +1
    -0
      changelog.d/10877.feature
  2. +34
    -0
      synapse/handlers/message.py
  3. +4
    -2
      synapse/rest/client/room_batch.py
  4. +4
    -2
      synapse/storage/databases/main/room_batch.py

+ 1
- 0
changelog.d/10877.feature 查看文件

@@ -0,0 +1 @@
Ensure `(room_id, next_batch_id)` is unique across [MSC2716](https://github.com/matrix-org/matrix-doc/pull/2716) insertion events in rooms to avoid cross-talk/conflicts between batches.

+ 34
- 0
synapse/handlers/message.py 查看文件

@@ -16,6 +16,7 @@
# limitations under the License.
import logging
import random
from http import HTTPStatus
from typing import TYPE_CHECKING, Any, Dict, List, Mapping, Optional, Tuple

from canonicaljson import encode_canonical_json
@@ -1461,6 +1462,39 @@ class EventCreationHandler:
if prev_state_ids:
raise AuthError(403, "Changing the room create event is forbidden")

if event.type == EventTypes.MSC2716_INSERTION:
room_version = await self.store.get_room_version_id(event.room_id)
room_version_obj = KNOWN_ROOM_VERSIONS[room_version]

create_event = await self.store.get_create_event_for_room(event.room_id)
room_creator = create_event.content.get(EventContentFields.ROOM_CREATOR)

# Only check an insertion event if the room version
# supports it or the event is from the room creator.
if room_version_obj.msc2716_historical or (
self.config.experimental.msc2716_enabled
and event.sender == room_creator
):
next_batch_id = event.content.get(
EventContentFields.MSC2716_NEXT_BATCH_ID
)
conflicting_insertion_event_id = (
await self.store.get_insertion_event_by_batch_id(
event.room_id, next_batch_id
)
)
if conflicting_insertion_event_id is not None:
# The current insertion event that we're processing is invalid
# because an insertion event already exists in the room with the
# same next_batch_id. We can't allow multiple because the batch
# pointing will get weird, e.g. we can't determine which insertion
# event the batch event is pointing to.
raise SynapseError(
HTTPStatus.BAD_REQUEST,
"Another insertion event already exists with the same next_batch_id",
errcode=Codes.INVALID_PARAM,
)

# Mark any `m.historical` messages as backfilled so they don't appear
# in `/sync` and have the proper decrementing `stream_ordering` as we import
backfilled = False


+ 4
- 2
synapse/rest/client/room_batch.py 查看文件

@@ -306,11 +306,13 @@ class RoomBatchSendEventRestServlet(RestServlet):
# Verify the batch_id_from_query corresponds to an actual insertion event
# and have the batch connected.
corresponding_insertion_event_id = (
await self.store.get_insertion_event_by_batch_id(batch_id_from_query)
await self.store.get_insertion_event_by_batch_id(
room_id, batch_id_from_query
)
)
if corresponding_insertion_event_id is None:
raise SynapseError(
400,
HTTPStatus.BAD_REQUEST,
"No insertion event corresponds to the given ?batch_id",
errcode=Codes.INVALID_PARAM,
)


+ 4
- 2
synapse/storage/databases/main/room_batch.py 查看文件

@@ -18,7 +18,9 @@ from synapse.storage._base import SQLBaseStore


class RoomBatchStore(SQLBaseStore):
async def get_insertion_event_by_batch_id(self, batch_id: str) -> Optional[str]:
async def get_insertion_event_by_batch_id(
self, room_id: str, batch_id: str
) -> Optional[str]:
"""Retrieve a insertion event ID.

Args:
@@ -30,7 +32,7 @@ class RoomBatchStore(SQLBaseStore):
"""
return await self.db_pool.simple_select_one_onecol(
table="insertion_events",
keyvalues={"next_batch_id": batch_id},
keyvalues={"room_id": room_id, "next_batch_id": batch_id},
retcol="event_id",
allow_none=True,
)

正在加载...
取消
保存