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

Commit

Permalink
Merge pull request #964 from matrix-org/erikj/fed_join_fix
Browse files Browse the repository at this point in the history
Handle the case of missing auth events when joining a room
  • Loading branch information
erikjohnston authored Jul 29, 2016
2 parents a679a01 + c51a52f commit cbea0c7
Showing 1 changed file with 31 additions and 4 deletions.
35 changes: 31 additions & 4 deletions synapse/handlers/federation.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def on_receive_pdu(self, origin, pdu, state=None, auth_chain=None):

try:
event_stream_id, max_stream_id = yield self._persist_auth_tree(
auth_chain, state, event
origin, auth_chain, state, event
)
except AuthError as e:
raise FederationError(
Expand Down Expand Up @@ -637,7 +637,7 @@ def do_invite_join(self, target_hosts, room_id, joinee, content):
pass

event_stream_id, max_stream_id = yield self._persist_auth_tree(
auth_chain, state, event
origin, auth_chain, state, event
)

with PreserveLoggingContext():
Expand Down Expand Up @@ -1155,11 +1155,19 @@ def _handle_new_events(self, origin, event_infos, backfilled=False):
)

@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
state and event. Then persists the auth chain and state atomically.
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:
2-tuple of (event_stream_id, max_stream_id) from the persist_event
call for `event`
Expand All @@ -1172,7 +1180,7 @@ def _persist_auth_tree(self, auth_events, state, event):

event_map = {
e.event_id: e
for e in auth_events
for e in itertools.chain(auth_events, state, [event])
}

create_event = None
Expand All @@ -1181,10 +1189,29 @@ def _persist_auth_tree(self, auth_events, state, event):
create_event = e
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]):
auth_for_e = {
(event_map[e_id].type, event_map[e_id].state_key): event_map[e_id]
for e_id, _ in e.auth_events
if e_id in event_map
}
if create_event:
auth_for_e[(EventTypes.Create, "")] = create_event
Expand Down

0 comments on commit cbea0c7

Please sign in to comment.