Hacks to work around #6605 (#6608)

When we have an event which refers to non-existent auth_events, ignore said events rather than exploding in a ball of fire.

Fixes #6605.
This commit is contained in:
Richard van der Hoff 2019-12-31 10:41:44 +00:00 committed by GitHub
parent f03c877b32
commit 92eac974b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 15 deletions

1
changelog.d/6608.bugfix Normal file
View File

@ -0,0 +1 @@
Fix exceptions caused by state resolution choking on malformed events.

View File

@ -183,16 +183,20 @@ def _get_power_level_for_sender(room_id, event_id, event_map, state_res_store):
pl = None pl = None
for aid in event.auth_event_ids(): for aid in event.auth_event_ids():
aev = yield _get_event(room_id, aid, event_map, state_res_store) aev = yield _get_event(
if (aev.type, aev.state_key) == (EventTypes.PowerLevels, ""): room_id, aid, event_map, state_res_store, allow_none=True
)
if aev and (aev.type, aev.state_key) == (EventTypes.PowerLevels, ""):
pl = aev pl = aev
break break
if pl is None: if pl is None:
# Couldn't find power level. Check if they're the creator of the room # Couldn't find power level. Check if they're the creator of the room
for aid in event.auth_event_ids(): for aid in event.auth_event_ids():
aev = yield _get_event(room_id, aid, event_map, state_res_store) aev = yield _get_event(
if (aev.type, aev.state_key) == (EventTypes.Create, ""): room_id, aid, event_map, state_res_store, allow_none=True
)
if aev and (aev.type, aev.state_key) == (EventTypes.Create, ""):
if aev.content.get("creator") == event.sender: if aev.content.get("creator") == event.sender:
return 100 return 100
break break
@ -403,10 +407,17 @@ def _iterative_auth_checks(
auth_events = {} auth_events = {}
for aid in event.auth_event_ids(): for aid in event.auth_event_ids():
ev = yield _get_event(room_id, aid, event_map, state_res_store) ev = yield _get_event(
room_id, aid, event_map, state_res_store, allow_none=True
)
if ev.rejected_reason is None: if not ev:
auth_events[(ev.type, ev.state_key)] = ev logger.warning(
"auth_event id %s for event %s is missing", aid, event_id
)
else:
if ev.rejected_reason is None:
auth_events[(ev.type, ev.state_key)] = ev
for key in event_auth.auth_types_for_event(event): for key in event_auth.auth_types_for_event(event):
if key in resolved_state: if key in resolved_state:
@ -457,8 +468,10 @@ def _mainline_sort(
auth_events = pl_ev.auth_event_ids() auth_events = pl_ev.auth_event_ids()
pl = None pl = None
for aid in auth_events: for aid in auth_events:
ev = yield _get_event(room_id, aid, event_map, state_res_store) ev = yield _get_event(
if (ev.type, ev.state_key) == (EventTypes.PowerLevels, ""): room_id, aid, event_map, state_res_store, allow_none=True
)
if ev and (ev.type, ev.state_key) == (EventTypes.PowerLevels, ""):
pl = aid pl = aid
break break
@ -506,8 +519,10 @@ def _get_mainline_depth_for_event(event, mainline_map, event_map, state_res_stor
event = None event = None
for aid in auth_events: for aid in auth_events:
aev = yield _get_event(room_id, aid, event_map, state_res_store) aev = yield _get_event(
if (aev.type, aev.state_key) == (EventTypes.PowerLevels, ""): room_id, aid, event_map, state_res_store, allow_none=True
)
if aev and (aev.type, aev.state_key) == (EventTypes.PowerLevels, ""):
event = aev event = aev
break break
@ -516,7 +531,7 @@ def _get_mainline_depth_for_event(event, mainline_map, event_map, state_res_stor
@defer.inlineCallbacks @defer.inlineCallbacks
def _get_event(room_id, event_id, event_map, state_res_store): def _get_event(room_id, event_id, event_map, state_res_store, allow_none=False):
"""Helper function to look up event in event_map, falling back to looking """Helper function to look up event in event_map, falling back to looking
it up in the store it up in the store
@ -525,15 +540,22 @@ def _get_event(room_id, event_id, event_map, state_res_store):
event_id (str) event_id (str)
event_map (dict[str,FrozenEvent]) event_map (dict[str,FrozenEvent])
state_res_store (StateResolutionStore) state_res_store (StateResolutionStore)
allow_none (bool): if the event is not found, return None rather than raising
an exception
Returns: Returns:
Deferred[FrozenEvent] Deferred[Optional[FrozenEvent]]
""" """
if event_id not in event_map: if event_id not in event_map:
events = yield state_res_store.get_events([event_id], allow_rejected=True) events = yield state_res_store.get_events([event_id], allow_rejected=True)
event_map.update(events) event_map.update(events)
event = event_map[event_id] event = event_map.get(event_id)
assert event is not None
if event is None:
if allow_none:
return None
raise Exception("Unknown event %s" % (event_id,))
if event.room_id != room_id: if event.room_id != room_id:
raise Exception( raise Exception(
"In state res for room %s, event %s is in %s" "In state res for room %s, event %s is in %s"