mirror of
https://git.anonymousland.org/anonymousland/synapse.git
synced 2025-08-06 10:14:14 -04:00
Fix bug which caused rejected events to be stored with the wrong room state (#6320)
Fixes a bug where rejected events were persisted with the wrong state group. Also fixes an occasional internal-server-error when receiving events over federation which are rejected and (possibly because they are backwards-extremities) have no prev_group. Fixes #6289.
This commit is contained in:
parent
0e3ab8afdc
commit
807ec3bd99
7 changed files with 283 additions and 101 deletions
|
@ -21,6 +21,7 @@ from synapse.api.auth import Auth
|
|||
from synapse.api.constants import EventTypes, Membership
|
||||
from synapse.api.room_versions import RoomVersions
|
||||
from synapse.events import FrozenEvent
|
||||
from synapse.events.snapshot import EventContext
|
||||
from synapse.state import StateHandler, StateResolutionHandler
|
||||
|
||||
from tests import unittest
|
||||
|
@ -198,16 +199,22 @@ class StateTestCase(unittest.TestCase):
|
|||
|
||||
self.store.register_events(graph.walk())
|
||||
|
||||
context_store = {}
|
||||
context_store = {} # type: dict[str, EventContext]
|
||||
|
||||
for event in graph.walk():
|
||||
context = yield self.state.compute_event_context(event)
|
||||
self.store.register_event_context(event, context)
|
||||
context_store[event.event_id] = context
|
||||
|
||||
prev_state_ids = yield context_store["D"].get_prev_state_ids(self.store)
|
||||
ctx_c = context_store["C"]
|
||||
ctx_d = context_store["D"]
|
||||
|
||||
prev_state_ids = yield ctx_d.get_prev_state_ids(self.store)
|
||||
self.assertEqual(2, len(prev_state_ids))
|
||||
|
||||
self.assertEqual(ctx_c.state_group, ctx_d.state_group_before_event)
|
||||
self.assertEqual(ctx_d.state_group_before_event, ctx_d.state_group)
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_branch_basic_conflict(self):
|
||||
graph = Graph(
|
||||
|
@ -241,12 +248,19 @@ class StateTestCase(unittest.TestCase):
|
|||
self.store.register_event_context(event, context)
|
||||
context_store[event.event_id] = context
|
||||
|
||||
prev_state_ids = yield context_store["D"].get_prev_state_ids(self.store)
|
||||
# C ends up winning the resolution between B and C
|
||||
|
||||
ctx_c = context_store["C"]
|
||||
ctx_d = context_store["D"]
|
||||
|
||||
prev_state_ids = yield ctx_d.get_prev_state_ids(self.store)
|
||||
self.assertSetEqual(
|
||||
{"START", "A", "C"}, {e_id for e_id in prev_state_ids.values()}
|
||||
)
|
||||
|
||||
self.assertEqual(ctx_c.state_group, ctx_d.state_group_before_event)
|
||||
self.assertEqual(ctx_d.state_group_before_event, ctx_d.state_group)
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_branch_have_banned_conflict(self):
|
||||
graph = Graph(
|
||||
|
@ -292,11 +306,18 @@ class StateTestCase(unittest.TestCase):
|
|||
self.store.register_event_context(event, context)
|
||||
context_store[event.event_id] = context
|
||||
|
||||
prev_state_ids = yield context_store["E"].get_prev_state_ids(self.store)
|
||||
# C ends up winning the resolution between C and D because bans win over other
|
||||
# changes
|
||||
|
||||
ctx_c = context_store["C"]
|
||||
ctx_e = context_store["E"]
|
||||
|
||||
prev_state_ids = yield ctx_e.get_prev_state_ids(self.store)
|
||||
self.assertSetEqual(
|
||||
{"START", "A", "B", "C"}, {e for e in prev_state_ids.values()}
|
||||
)
|
||||
self.assertEqual(ctx_c.state_group, ctx_e.state_group_before_event)
|
||||
self.assertEqual(ctx_e.state_group_before_event, ctx_e.state_group)
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_branch_have_perms_conflict(self):
|
||||
|
@ -360,12 +381,20 @@ class StateTestCase(unittest.TestCase):
|
|||
self.store.register_event_context(event, context)
|
||||
context_store[event.event_id] = context
|
||||
|
||||
prev_state_ids = yield context_store["D"].get_prev_state_ids(self.store)
|
||||
# B ends up winning the resolution between B and C because power levels
|
||||
# win over other changes.
|
||||
|
||||
ctx_b = context_store["B"]
|
||||
ctx_d = context_store["D"]
|
||||
|
||||
prev_state_ids = yield ctx_d.get_prev_state_ids(self.store)
|
||||
self.assertSetEqual(
|
||||
{"A1", "A2", "A3", "A5", "B"}, {e for e in prev_state_ids.values()}
|
||||
)
|
||||
|
||||
self.assertEqual(ctx_b.state_group, ctx_d.state_group_before_event)
|
||||
self.assertEqual(ctx_d.state_group_before_event, ctx_d.state_group)
|
||||
|
||||
def _add_depths(self, nodes, edges):
|
||||
def _get_depth(ev):
|
||||
node = nodes[ev]
|
||||
|
@ -390,13 +419,16 @@ class StateTestCase(unittest.TestCase):
|
|||
|
||||
context = yield self.state.compute_event_context(event, old_state=old_state)
|
||||
|
||||
current_state_ids = yield context.get_current_state_ids(self.store)
|
||||
prev_state_ids = yield context.get_prev_state_ids(self.store)
|
||||
self.assertCountEqual((e.event_id for e in old_state), prev_state_ids.values())
|
||||
|
||||
self.assertEqual(
|
||||
set(e.event_id for e in old_state), set(current_state_ids.values())
|
||||
current_state_ids = yield context.get_current_state_ids(self.store)
|
||||
self.assertCountEqual(
|
||||
(e.event_id for e in old_state), current_state_ids.values()
|
||||
)
|
||||
|
||||
self.assertIsNotNone(context.state_group)
|
||||
self.assertIsNotNone(context.state_group_before_event)
|
||||
self.assertEqual(context.state_group_before_event, context.state_group)
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_annotate_with_old_state(self):
|
||||
|
@ -411,11 +443,18 @@ class StateTestCase(unittest.TestCase):
|
|||
context = yield self.state.compute_event_context(event, old_state=old_state)
|
||||
|
||||
prev_state_ids = yield context.get_prev_state_ids(self.store)
|
||||
self.assertCountEqual((e.event_id for e in old_state), prev_state_ids.values())
|
||||
|
||||
self.assertEqual(
|
||||
set(e.event_id for e in old_state), set(prev_state_ids.values())
|
||||
current_state_ids = yield context.get_current_state_ids(self.store)
|
||||
self.assertCountEqual(
|
||||
(e.event_id for e in old_state + [event]), current_state_ids.values()
|
||||
)
|
||||
|
||||
self.assertIsNotNone(context.state_group_before_event)
|
||||
self.assertNotEqual(context.state_group_before_event, context.state_group)
|
||||
self.assertEqual(context.state_group_before_event, context.prev_group)
|
||||
self.assertEqual({("state", ""): event.event_id}, context.delta_ids)
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_trivial_annotate_message(self):
|
||||
prev_event_id = "prev_event_id"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue