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

Commit 5e7d75d

Browse files
authored
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 28877fa commit 5e7d75d

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
@@ -658,7 +658,7 @@ async def _get_mainline_depth_for_event(
658658
# We do an iterative search, replacing `event with the power level in its
659659
# auth events (if any)
660660
while tmp_event:
661-
depth = mainline_map.get(event.event_id)
661+
depth = mainline_map.get(tmp_event.event_id)
662662
if depth is not None:
663663
return depth
664664

tests/state/test_v2.py

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ def to_event(self, auth_events, prev_events):
8888
event_dict = {
8989
"auth_events": [(a, {}) for a in auth_events],
9090
"prev_events": [(p, {}) for p in prev_events],
91-
"event_id": self.node_id,
91+
"event_id": self.event_id,
9292
"sender": self.sender,
9393
"type": self.type,
9494
"content": self.content,
@@ -381,6 +381,61 @@ def test_topic(self):
381381

382382
self.do_check(events, edges, expected_state_ids)
383383

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

0 commit comments

Comments
 (0)