From 5d051b2da29cee2673ca039b64da6cf8ba00f335 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Mon, 20 Sep 2021 18:20:17 +0100 Subject: [PATCH] Stop trying to auth/persist events whose auth events we do not have. --- changelog.d/10907.bugfix | 1 + synapse/handlers/federation_event.py | 24 ++++++++++++++++-------- 2 files changed, 17 insertions(+), 8 deletions(-) create mode 100644 changelog.d/10907.bugfix diff --git a/changelog.d/10907.bugfix b/changelog.d/10907.bugfix new file mode 100644 index 000000000000..601b341f9fa6 --- /dev/null +++ b/changelog.d/10907.bugfix @@ -0,0 +1 @@ +Fix a long-standing bug which could cause events pulled over federation to be incorrectly rejected. diff --git a/synapse/handlers/federation_event.py b/synapse/handlers/federation_event.py index 8fd9e51044d6..01fd84112252 100644 --- a/synapse/handlers/federation_event.py +++ b/synapse/handlers/federation_event.py @@ -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( @@ -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, @@ -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.