@@ -2040,8 +2040,10 @@ def do_auth(self, origin, event, context, auth_events):
20402040 auth_events (dict[(str, str)->synapse.events.EventBase]):
20412041 Map from (event_type, state_key) to event
20422042
2043- What we expect the event's auth_events to be, based on the event's
2044- position in the dag. I think? maybe??
2043+ Normally, our calculated auth_events based on the state of the room
2044+ at the event's position in the DAG, though occasionally (eg if the
2045+ event is an outlier), may be the auth events claimed by the remote
2046+ server.
20452047
20462048 Also NB that this function adds entries to it.
20472049 Returns:
@@ -2091,30 +2093,35 @@ def _update_auth_events_and_context_for_auth(
20912093 origin (str):
20922094 event (synapse.events.EventBase):
20932095 context (synapse.events.snapshot.EventContext):
2096+
20942097 auth_events (dict[(str, str)->synapse.events.EventBase]):
2098+ Map from (event_type, state_key) to event
2099+
2100+ Normally, our calculated auth_events based on the state of the room
2101+ at the event's position in the DAG, though occasionally (eg if the
2102+ event is an outlier), may be the auth events claimed by the remote
2103+ server.
2104+
2105+ Also NB that this function adds entries to it.
20952106
20962107 Returns:
20972108 defer.Deferred[EventContext]: updated context
20982109 """
20992110 event_auth_events = set (event .auth_event_ids ())
21002111
2101- if event .is_state ():
2102- event_key = (event .type , event .state_key )
2103- else :
2104- event_key = None
2105-
2106- # if the event's auth_events refers to events which are not in our
2107- # calculated auth_events, we need to fetch those events from somewhere.
2108- #
2109- # we start by fetching them from the store, and then try calling /event_auth/.
2112+ # missing_auth is the set of the event's auth_events which we don't yet have
2113+ # in auth_events.
21102114 missing_auth = event_auth_events .difference (
21112115 e .event_id for e in auth_events .values ()
21122116 )
21132117
2118+ # if we have missing events, we need to fetch those events from somewhere.
2119+ #
2120+ # we start by checking if they are in the store, and then try calling /event_auth/.
21142121 if missing_auth :
21152122 # TODO: can we use store.have_seen_events here instead?
21162123 have_events = yield self .store .get_seen_events_with_rejections (missing_auth )
2117- logger .debug ("Got events %s from store" , have_events )
2124+ logger .debug ("Found events %s in the store" , have_events )
21182125 missing_auth .difference_update (have_events .keys ())
21192126 else :
21202127 have_events = {}
@@ -2169,15 +2176,17 @@ def _update_auth_events_and_context_for_auth(
21692176 event .auth_event_ids ()
21702177 )
21712178 except Exception :
2172- # FIXME:
21732179 logger .exception ("Failed to get auth chain" )
21742180
21752181 if event .internal_metadata .is_outlier ():
2182+ # XXX: given that, for an outlier, we'll be working with the
2183+ # event's *claimed* auth events rather than those we calculated:
2184+ # (a) is there any point in this test, since different_auth below will
2185+ # obviously be empty
2186+ # (b) alternatively, why don't we do it earlier?
21762187 logger .info ("Skipping auth_event fetch for outlier" )
21772188 return context
21782189
2179- # FIXME: Assumes we have and stored all the state for all the
2180- # prev_events
21812190 different_auth = event_auth_events .difference (
21822191 e .event_id for e in auth_events .values ()
21832192 )
@@ -2191,27 +2200,22 @@ def _update_auth_events_and_context_for_auth(
21912200 different_auth ,
21922201 )
21932202
2203+ # now we state-resolve between our own idea of the auth events, and the remote's
2204+ # idea of them.
2205+
21942206 room_version = yield self .store .get_room_version (event .room_id )
2207+ different_event_ids = [
2208+ d for d in different_auth if d in have_events and not have_events [d ]
2209+ ]
21952210
2196- different_events = yield make_deferred_yieldable (
2197- defer .gatherResults (
2198- [
2199- run_in_background (
2200- self .store .get_event , d , allow_none = True , allow_rejected = False
2201- )
2202- for d in different_auth
2203- if d in have_events and not have_events [d ]
2204- ],
2205- consumeErrors = True ,
2206- )
2207- ).addErrback (unwrapFirstError )
2211+ if different_event_ids :
2212+ # XXX: currently this checks for redactions but I'm not convinced that is
2213+ # necessary?
2214+ different_events = yield self .store .get_events_as_list (different_event_ids )
22082215
2209- if different_events :
22102216 local_view = dict (auth_events )
22112217 remote_view = dict (auth_events )
2212- remote_view .update (
2213- {(d .type , d .state_key ): d for d in different_events if d }
2214- )
2218+ remote_view .update ({(d .type , d .state_key ): d for d in different_events })
22152219
22162220 new_state = yield self .state_handler .resolve_events (
22172221 room_version ,
@@ -2231,13 +2235,13 @@ def _update_auth_events_and_context_for_auth(
22312235 auth_events .update (new_state )
22322236
22332237 context = yield self ._update_context_for_auth_events (
2234- event , context , auth_events , event_key
2238+ event , context , auth_events
22352239 )
22362240
22372241 return context
22382242
22392243 @defer .inlineCallbacks
2240- def _update_context_for_auth_events (self , event , context , auth_events , event_key ):
2244+ def _update_context_for_auth_events (self , event , context , auth_events ):
22412245 """Update the state_ids in an event context after auth event resolution,
22422246 storing the changes as a new state group.
22432247
@@ -2246,18 +2250,21 @@ def _update_context_for_auth_events(self, event, context, auth_events, event_key
22462250
22472251 context (synapse.events.snapshot.EventContext): initial event context
22482252
2249- auth_events (dict[(str, str)->str ]): Events to update in the event
2253+ auth_events (dict[(str, str)->EventBase ]): Events to update in the event
22502254 context.
22512255
2252- event_key ((str, str)): (type, state_key) for the current event.
2253- this will not be included in the current_state in the context.
2254-
22552256 Returns:
22562257 Deferred[EventContext]: new event context
22572258 """
2259+ # exclude the state key of the new event from the current_state in the context.
2260+ if event .is_state ():
2261+ event_key = (event .type , event .state_key )
2262+ else :
2263+ event_key = None
22582264 state_updates = {
22592265 k : a .event_id for k , a in iteritems (auth_events ) if k != event_key
22602266 }
2267+
22612268 current_state_ids = yield context .get_current_state_ids (self .store )
22622269 current_state_ids = dict (current_state_ids )
22632270
0 commit comments