Skip to content
Snippets Groups Projects
Commit cbea0c70 authored by Erik Johnston's avatar Erik Johnston Committed by GitHub
Browse files

Merge pull request #964 from matrix-org/erikj/fed_join_fix

Handle the case of missing auth events when joining a room
parents a679a01d c51a52f3
No related branches found
No related tags found
No related merge requests found
...@@ -124,7 +124,7 @@ class FederationHandler(BaseHandler): ...@@ -124,7 +124,7 @@ class FederationHandler(BaseHandler):
try: try:
event_stream_id, max_stream_id = yield self._persist_auth_tree( event_stream_id, max_stream_id = yield self._persist_auth_tree(
auth_chain, state, event origin, auth_chain, state, event
) )
except AuthError as e: except AuthError as e:
raise FederationError( raise FederationError(
...@@ -637,7 +637,7 @@ class FederationHandler(BaseHandler): ...@@ -637,7 +637,7 @@ class FederationHandler(BaseHandler):
pass pass
event_stream_id, max_stream_id = yield self._persist_auth_tree( event_stream_id, max_stream_id = yield self._persist_auth_tree(
auth_chain, state, event origin, auth_chain, state, event
) )
with PreserveLoggingContext(): with PreserveLoggingContext():
...@@ -1155,11 +1155,19 @@ class FederationHandler(BaseHandler): ...@@ -1155,11 +1155,19 @@ class FederationHandler(BaseHandler):
) )
@defer.inlineCallbacks @defer.inlineCallbacks
def _persist_auth_tree(self, auth_events, state, event): def _persist_auth_tree(self, origin, auth_events, state, event):
"""Checks the auth chain is valid (and passes auth checks) for the """Checks the auth chain is valid (and passes auth checks) for the
state and event. Then persists the auth chain and state atomically. state and event. Then persists the auth chain and state atomically.
Persists the event seperately. Persists the event seperately.
Will attempt to fetch missing auth events.
Args:
origin (str): Where the events came from
auth_events (list)
state (list)
event (Event)
Returns: Returns:
2-tuple of (event_stream_id, max_stream_id) from the persist_event 2-tuple of (event_stream_id, max_stream_id) from the persist_event
call for `event` call for `event`
...@@ -1172,7 +1180,7 @@ class FederationHandler(BaseHandler): ...@@ -1172,7 +1180,7 @@ class FederationHandler(BaseHandler):
event_map = { event_map = {
e.event_id: e e.event_id: e
for e in auth_events for e in itertools.chain(auth_events, state, [event])
} }
create_event = None create_event = None
...@@ -1181,10 +1189,29 @@ class FederationHandler(BaseHandler): ...@@ -1181,10 +1189,29 @@ class FederationHandler(BaseHandler):
create_event = e create_event = e
break break
missing_auth_events = set()
for e in itertools.chain(auth_events, state, [event]):
for e_id, _ in e.auth_events:
if e_id not in event_map:
missing_auth_events.add(e_id)
for e_id in missing_auth_events:
m_ev = yield self.replication_layer.get_pdu(
[origin],
e_id,
outlier=True,
timeout=10000,
)
if m_ev and m_ev.event_id == e_id:
event_map[e_id] = m_ev
else:
logger.info("Failed to find auth event %r", e_id)
for e in itertools.chain(auth_events, state, [event]): for e in itertools.chain(auth_events, state, [event]):
auth_for_e = { auth_for_e = {
(event_map[e_id].type, event_map[e_id].state_key): event_map[e_id] (event_map[e_id].type, event_map[e_id].state_key): event_map[e_id]
for e_id, _ in e.auth_events for e_id, _ in e.auth_events
if e_id in event_map
} }
if create_event: if create_event:
auth_for_e[(EventTypes.Create, "")] = create_event auth_for_e[(EventTypes.Create, "")] = create_event
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment