@@ -581,6 +581,13 @@ async def update_state_for_partial_state_event(
581581 event .event_id ,
582582 )
583583 return
584+
585+ # since the state at this event has changed, we should now re-evaluate
586+ # whether it should have been rejected. We must already have all of the
587+ # auth events (from last time we went round this path), so there is no
588+ # need to pass the origin.
589+ await self ._check_event_auth (None , event , context )
590+
584591 await self ._store .update_state_for_partial_state_event (event , context )
585592 self ._state_storage_controller .notify_event_un_partial_stated (
586593 event .event_id
@@ -1624,13 +1631,15 @@ async def prep(event: EventBase) -> None:
16241631 )
16251632
16261633 async def _check_event_auth (
1627- self , origin : str , event : EventBase , context : EventContext
1634+ self , origin : Optional [ str ] , event : EventBase , context : EventContext
16281635 ) -> None :
16291636 """
16301637 Checks whether an event should be rejected (for failing auth checks).
16311638
16321639 Args:
1633- origin: The host the event originates from.
1640+ origin: The host the event originates from. This is used to fetch
1641+ any missing auth events. It can be set to None, but only if we are
1642+ sure that we already have all the auth events.
16341643 event: The event itself.
16351644 context:
16361645 The event context.
@@ -1876,7 +1885,7 @@ async def _check_for_soft_fail(
18761885 event .internal_metadata .soft_failed = True
18771886
18781887 async def _load_or_fetch_auth_events_for_event (
1879- self , destination : str , event : EventBase
1888+ self , destination : Optional [ str ] , event : EventBase
18801889 ) -> Collection [EventBase ]:
18811890 """Fetch this event's auth_events, from database or remote
18821891
@@ -1892,12 +1901,19 @@ async def _load_or_fetch_auth_events_for_event(
18921901 Args:
18931902 destination: where to send the /event_auth request. Typically the server
18941903 that sent us `event` in the first place.
1904+
1905+ If this is None, no attempt is made to load any missing auth events:
1906+ rather, an AssertionError is raised if there are any missing events.
1907+
18951908 event: the event whose auth_events we want
18961909
18971910 Returns:
18981911 all of the events listed in `event.auth_events_ids`, after deduplication
18991912
19001913 Raises:
1914+ AssertionError if some auth events were missing and no `destination` was
1915+ supplied.
1916+
19011917 AuthError if we were unable to fetch the auth_events for any reason.
19021918 """
19031919 event_auth_event_ids = set (event .auth_event_ids ())
@@ -1909,6 +1925,13 @@ async def _load_or_fetch_auth_events_for_event(
19091925 )
19101926 if not missing_auth_event_ids :
19111927 return event_auth_events .values ()
1928+ if destination is None :
1929+ # this shouldn't happen: destination must be set unless we know we have already
1930+ # persisted the auth events.
1931+ raise AssertionError (
1932+ "_load_or_fetch_auth_events_for_event() called with no destination for "
1933+ "an event with missing auth_events"
1934+ )
19121935
19131936 logger .info (
19141937 "Event %s refers to unknown auth events %s: fetching auth chain" ,
0 commit comments