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

Stop prematurely rejecting outlier events with missing auth_events #10907

Merged
merged 1 commit into from
Sep 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/10907.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix a long-standing bug which could cause events pulled over federation to be incorrectly rejected.
24 changes: 16 additions & 8 deletions synapse/handlers/federation_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -1194,10 +1194,17 @@ async def prep(event: EventBase) -> Optional[Tuple[EventBase, EventContext]]:
auth = {}
for auth_event_id in event.auth_event_ids():
ae = persisted_events.get(auth_event_id)
if ae:
auth[(ae.type, ae.state_key)] = ae
else:
logger.info("Missing auth event %s", auth_event_id)
if not ae:
logger.warning(
"Event %s relies on auth_event %s, which could not be found.",
event,
auth_event_id,
)
# the fact we can't find the auth event doesn't mean it doesn't
# exist, which means it is premature to reject `event`. Instead we
# just ignore it for now.
return None
auth[(ae.type, ae.state_key)] = ae

context = EventContext.for_outlier()
context = await self._check_event_auth(
Expand All @@ -1208,8 +1215,10 @@ async def prep(event: EventBase) -> Optional[Tuple[EventBase, EventContext]]:
)
return event, context

events_to_persist = await yieldable_gather_results(prep, fetched_events)
await self.persist_events_and_notify(room_id, events_to_persist)
events_to_persist = (
x for x in await yieldable_gather_results(prep, fetched_events) if x
)
await self.persist_events_and_notify(room_id, tuple(events_to_persist))

async def _check_event_auth(
self,
Expand All @@ -1235,8 +1244,7 @@ async def _check_event_auth(

claimed_auth_event_map:
A map of (type, state_key) => event for the event's claimed auth_events.
Possibly incomplete, and possibly including events that are not yet
persisted, or authed, or in the right room.
Possibly including events that were rejected, or are in the wrong room.

Only populated when populating outliers.

Expand Down