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.
This commit is contained in:
parent
28877fade9
commit
5e7d75daa2
|
@ -0,0 +1 @@
|
||||||
|
Fix small bug in v2 state resolution algorithm, which could also cause performance issues for rooms with large numbers of power levels.
|
|
@ -658,7 +658,7 @@ async def _get_mainline_depth_for_event(
|
||||||
# We do an iterative search, replacing `event with the power level in its
|
# We do an iterative search, replacing `event with the power level in its
|
||||||
# auth events (if any)
|
# auth events (if any)
|
||||||
while tmp_event:
|
while tmp_event:
|
||||||
depth = mainline_map.get(event.event_id)
|
depth = mainline_map.get(tmp_event.event_id)
|
||||||
if depth is not None:
|
if depth is not None:
|
||||||
return depth
|
return depth
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,7 @@ class FakeEvent:
|
||||||
event_dict = {
|
event_dict = {
|
||||||
"auth_events": [(a, {}) for a in auth_events],
|
"auth_events": [(a, {}) for a in auth_events],
|
||||||
"prev_events": [(p, {}) for p in prev_events],
|
"prev_events": [(p, {}) for p in prev_events],
|
||||||
"event_id": self.node_id,
|
"event_id": self.event_id,
|
||||||
"sender": self.sender,
|
"sender": self.sender,
|
||||||
"type": self.type,
|
"type": self.type,
|
||||||
"content": self.content,
|
"content": self.content,
|
||||||
|
@ -381,6 +381,61 @@ class StateTestCase(unittest.TestCase):
|
||||||
|
|
||||||
self.do_check(events, edges, expected_state_ids)
|
self.do_check(events, edges, expected_state_ids)
|
||||||
|
|
||||||
|
def test_mainline_sort(self):
|
||||||
|
"""Tests that the mainline ordering works correctly.
|
||||||
|
"""
|
||||||
|
|
||||||
|
events = [
|
||||||
|
FakeEvent(
|
||||||
|
id="T1", sender=ALICE, type=EventTypes.Topic, state_key="", content={}
|
||||||
|
),
|
||||||
|
FakeEvent(
|
||||||
|
id="PA1",
|
||||||
|
sender=ALICE,
|
||||||
|
type=EventTypes.PowerLevels,
|
||||||
|
state_key="",
|
||||||
|
content={"users": {ALICE: 100, BOB: 50}},
|
||||||
|
),
|
||||||
|
FakeEvent(
|
||||||
|
id="T2", sender=ALICE, type=EventTypes.Topic, state_key="", content={}
|
||||||
|
),
|
||||||
|
FakeEvent(
|
||||||
|
id="PA2",
|
||||||
|
sender=ALICE,
|
||||||
|
type=EventTypes.PowerLevels,
|
||||||
|
state_key="",
|
||||||
|
content={
|
||||||
|
"users": {ALICE: 100, BOB: 50},
|
||||||
|
"events": {EventTypes.PowerLevels: 100},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
FakeEvent(
|
||||||
|
id="PB",
|
||||||
|
sender=BOB,
|
||||||
|
type=EventTypes.PowerLevels,
|
||||||
|
state_key="",
|
||||||
|
content={"users": {ALICE: 100, BOB: 50}},
|
||||||
|
),
|
||||||
|
FakeEvent(
|
||||||
|
id="T3", sender=BOB, type=EventTypes.Topic, state_key="", content={}
|
||||||
|
),
|
||||||
|
FakeEvent(
|
||||||
|
id="T4", sender=ALICE, type=EventTypes.Topic, state_key="", content={}
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
edges = [
|
||||||
|
["END", "T3", "PA2", "T2", "PA1", "T1", "START"],
|
||||||
|
["END", "T4", "PB", "PA1"],
|
||||||
|
]
|
||||||
|
|
||||||
|
# We expect T3 to be picked as the other topics are pointing at older
|
||||||
|
# power levels. Note that without mainline ordering we'd pick T4 due to
|
||||||
|
# it being sent *after* T3.
|
||||||
|
expected_state_ids = ["T3", "PA2"]
|
||||||
|
|
||||||
|
self.do_check(events, edges, expected_state_ids)
|
||||||
|
|
||||||
def do_check(self, events, edges, expected_state_ids):
|
def do_check(self, events, edges, expected_state_ids):
|
||||||
"""Take a list of events and edges and calculate the state of the
|
"""Take a list of events and edges and calculate the state of the
|
||||||
graph at END, and asserts it matches `expected_state_ids`
|
graph at END, and asserts it matches `expected_state_ids`
|
||||||
|
|
Loading…
Reference in New Issue