Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Commit a617b9f

Browse files
committed
Fix mainline ordering in state res v2 (#8971)
This had two effects 1) it'd give the wrong answer and b) would iterate *all* power levels in the auth chain of each event. The latter of which can be *very* expensive for certain types of IRC bridge rooms that have large numbers of power level changes.
1 parent 0cbac08 commit a617b9f

File tree

3 files changed

+58
-2
lines changed

3 files changed

+58
-2
lines changed

changelog.d/8971.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix small bug in v2 state resolution algorithm, which could also cause performance issues for rooms with large numbers of power levels.

synapse/state/v2.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,7 @@ async def _get_mainline_depth_for_event(
574574
# We do an iterative search, replacing `event with the power level in its
575575
# auth events (if any)
576576
while tmp_event:
577-
depth = mainline_map.get(event.event_id)
577+
depth = mainline_map.get(tmp_event.event_id)
578578
if depth is not None:
579579
return depth
580580

tests/state/test_v2.py

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ def to_event(self, auth_events, prev_events):
8484
event_dict = {
8585
"auth_events": [(a, {}) for a in auth_events],
8686
"prev_events": [(p, {}) for p in prev_events],
87-
"event_id": self.node_id,
87+
"event_id": self.event_id,
8888
"sender": self.sender,
8989
"type": self.type,
9090
"content": self.content,
@@ -377,6 +377,61 @@ def test_topic(self):
377377

378378
self.do_check(events, edges, expected_state_ids)
379379

380+
def test_mainline_sort(self):
381+
"""Tests that the mainline ordering works correctly.
382+
"""
383+
384+
events = [
385+
FakeEvent(
386+
id="T1", sender=ALICE, type=EventTypes.Topic, state_key="", content={}
387+
),
388+
FakeEvent(
389+
id="PA1",
390+
sender=ALICE,
391+
type=EventTypes.PowerLevels,
392+
state_key="",
393+
content={"users": {ALICE: 100, BOB: 50}},
394+
),
395+
FakeEvent(
396+
id="T2", sender=ALICE, type=EventTypes.Topic, state_key="", content={}
397+
),
398+
FakeEvent(
399+
id="PA2",
400+
sender=ALICE,
401+
type=EventTypes.PowerLevels,
402+
state_key="",
403+
content={
404+
"users": {ALICE: 100, BOB: 50},
405+
"events": {EventTypes.PowerLevels: 100},
406+
},
407+
),
408+
FakeEvent(
409+
id="PB",
410+
sender=BOB,
411+
type=EventTypes.PowerLevels,
412+
state_key="",
413+
content={"users": {ALICE: 100, BOB: 50}},
414+
),
415+
FakeEvent(
416+
id="T3", sender=BOB, type=EventTypes.Topic, state_key="", content={}
417+
),
418+
FakeEvent(
419+
id="T4", sender=ALICE, type=EventTypes.Topic, state_key="", content={}
420+
),
421+
]
422+
423+
edges = [
424+
["END", "T3", "PA2", "T2", "PA1", "T1", "START"],
425+
["END", "T4", "PB", "PA1"],
426+
]
427+
428+
# We expect T3 to be picked as the other topics are pointing at older
429+
# power levels. Note that without mainline ordering we'd pick T4 due to
430+
# it being sent *after* T3.
431+
expected_state_ids = ["T3", "PA2"]
432+
433+
self.do_check(events, edges, expected_state_ids)
434+
380435
def do_check(self, events, edges, expected_state_ids):
381436
"""Take a list of events and edges and calculate the state of the
382437
graph at END, and asserts it matches `expected_state_ids`

0 commit comments

Comments
 (0)