Don't query auth if the only difference is events that were rejected due to auth.

This commit is contained in:
Erik Johnston 2015-02-06 14:16:50 +00:00
parent c78b5fb1f1
commit e890ce223c
1 changed files with 67 additions and 51 deletions

View File

@ -791,12 +791,12 @@ class FederationHandler(BaseHandler):
@log_function @log_function
def do_auth(self, origin, event, context, auth_events): def do_auth(self, origin, event, context, auth_events):
# Check if we have all the auth events. # Check if we have all the auth events.
res = yield self.store.have_events( have_events = yield self.store.have_events(
[e_id for e_id, _ in event.auth_events] [e_id for e_id, _ in event.auth_events]
) )
event_auth_events = set(e_id for e_id, _ in event.auth_events) event_auth_events = set(e_id for e_id, _ in event.auth_events)
seen_events = set(res.keys()) seen_events = set(have_events.keys())
missing_auth = event_auth_events - seen_events missing_auth = event_auth_events - seen_events
@ -839,6 +839,11 @@ class FederationHandler(BaseHandler):
auth_events[(e.type, e.state_key)] = e auth_events[(e.type, e.state_key)] = e
except AuthError: except AuthError:
pass pass
have_events = yield self.store.have_events(
[e_id for e_id, _ in event.auth_events]
)
seen_events = set(have_events.keys())
except: except:
# FIXME: # FIXME:
logger.exception("Failed to get auth chain") logger.exception("Failed to get auth chain")
@ -852,64 +857,75 @@ class FederationHandler(BaseHandler):
# Do auth conflict res. # Do auth conflict res.
logger.debug("Different auth: %s", different_auth) logger.debug("Different auth: %s", different_auth)
# 1. Get what we think is the auth chain. # Only do auth resolution if we have something new to say.
auth_ids = self.auth.compute_auth_events( # We can't rove an auth failure.
event, context.current_state do_resolution = False
) for e_id in different_auth:
local_auth_chain = yield self.store.get_auth_chain(auth_ids) if e_id in have_events:
if have_events[e_id] != RejectedReason.AUTH_ERROR:
do_resolution = True
break
try: if do_resolution:
# 2. Get remote difference. # 1. Get what we think is the auth chain.
result = yield self.replication_layer.query_auth( auth_ids = self.auth.compute_auth_events(
origin, event, context.current_state
event.room_id,
event.event_id,
local_auth_chain,
) )
local_auth_chain = yield self.store.get_auth_chain(auth_ids)
seen_remotes = yield self.store.have_events( try:
[e.event_id for e in result["auth_chain"]] # 2. Get remote difference.
) result = yield self.replication_layer.query_auth(
origin,
event.room_id,
event.event_id,
local_auth_chain,
)
# 3. Process any remote auth chain events we haven't seen. seen_remotes = yield self.store.have_events(
for ev in result["auth_chain"]: [e.event_id for e in result["auth_chain"]]
if ev.event_id in seen_remotes.keys(): )
continue
if ev.event_id == event.event_id: # 3. Process any remote auth chain events we haven't seen.
continue for ev in result["auth_chain"]:
if ev.event_id in seen_remotes.keys():
continue
try: if ev.event_id == event.event_id:
auth_ids = [e_id for e_id, _ in ev.auth_events] continue
auth = {
(e.type, e.state_key): e for e in result["auth_chain"]
if e.event_id in auth_ids
}
ev.internal_metadata.outlier = True
logger.debug( try:
"do_auth %s different_auth: %s", auth_ids = [e_id for e_id, _ in ev.auth_events]
event.event_id, e.event_id auth = {
) (e.type, e.state_key): e
for e in result["auth_chain"]
if e.event_id in auth_ids
}
ev.internal_metadata.outlier = True
yield self._handle_new_event( logger.debug(
origin, ev, auth_events=auth "do_auth %s different_auth: %s",
) event.event_id, e.event_id
)
if ev.event_id in event_auth_events: yield self._handle_new_event(
auth_events[(ev.type, ev.state_key)] = ev origin, ev, auth_events=auth
except AuthError: )
pass
except: if ev.event_id in event_auth_events:
# FIXME: auth_events[(ev.type, ev.state_key)] = ev
logger.exception("Failed to query auth chain") except AuthError:
pass
# 4. Look at rejects and their proofs. except:
# TODO. # FIXME:
logger.exception("Failed to query auth chain")
context.current_state.update(auth_events) # 4. Look at rejects and their proofs.
context.state_group = None # TODO.
context.current_state.update(auth_events)
context.state_group = None
try: try:
self.auth.check(event, auth_events=auth_events) self.auth.check(event, auth_events=auth_events)
@ -1028,9 +1044,9 @@ class FederationHandler(BaseHandler):
for e in base_remote_rejected: for e in base_remote_rejected:
reason = yield self.store.get_rejection_reason(e.event_id) reason = yield self.store.get_rejection_reason(e.event_id)
if reason is None: if reason is None:
# FIXME: ERRR?! # TODO: e is not in the current state, so we should
logger.warn("Could not find reason for %s", e.event_id) # construct some proof of that.
raise RuntimeError("Could not find reason for %s" % e.event_id) continue
reason_map[e.event_id] = reason reason_map[e.event_id] = reason