Fix bug where we superfluously asked for current state. Change API of /query_auth/ so that we don't duplicate events in the response.

This commit is contained in:
Erik Johnston 2015-01-30 13:34:01 +00:00
parent 0adf3e5445
commit a70a801184
5 changed files with 43 additions and 49 deletions

View file

@ -102,6 +102,8 @@ class Auth(object):
def check_host_in_room(self, room_id, host): def check_host_in_room(self, room_id, host):
curr_state = yield self.state.get_current_state(room_id) curr_state = yield self.state.get_current_state(room_id)
logger.debug("Got curr_state %s", curr_state)
for event in curr_state: for event in curr_state:
if event.type == EventTypes.Member: if event.type == EventTypes.Member:
try: try:

View file

@ -357,15 +357,10 @@ class FederationClient(object):
for e in content["auth_chain"] for e in content["auth_chain"]
] ]
missing = [
(yield self._check_sigs_and_hash(self.event_from_pdu_json(e)))
for e in content.get("missing", [])
]
ret = { ret = {
"auth_chain": auth_chain, "auth_chain": auth_chain,
"rejects": content.get("rejects", []), "rejects": content.get("rejects", []),
"missing": missing, "missing": content.get("missing", []),
} }
defer.returnValue(ret) defer.returnValue(ret)

View file

@ -252,11 +252,8 @@ class FederationServer(object):
e.get_pdu_json(time_now) e.get_pdu_json(time_now)
for e in ret["auth_chain"] for e in ret["auth_chain"]
], ],
"rejects": content.get("rejects", []), "rejects": ret.get("rejects", []),
"missing": [ "missing": ret.get("missing", []),
e.get_pdu_json(time_now)
for e in ret.get("missing", [])
],
} }
defer.returnValue( defer.returnValue(
@ -372,6 +369,9 @@ class FederationServer(object):
logger.exception("Failed to get PDU") logger.exception("Failed to get PDU")
fetch_state = True fetch_state = True
else: else:
prevs = {e_id for e_id, _ in pdu.prev_events}
seen = set(have_seen.keys())
if prevs - seen:
fetch_state = True fetch_state = True
else: else:
fetch_state = True fetch_state = True

View file

@ -121,38 +121,18 @@ class FederationHandler(BaseHandler):
) )
if not is_in_room and not event.internal_metadata.is_outlier(): if not is_in_room and not event.internal_metadata.is_outlier():
logger.debug("Got event for room we're not in.") logger.debug("Got event for room we're not in.")
replication = self.replication_layer
if not state:
state, auth_chain = yield replication.get_state_for_room(
origin, room_id=event.room_id, event_id=event.event_id,
)
if not auth_chain:
auth_chain = yield replication.get_event_auth(
origin,
context=event.room_id,
event_id=event.event_id,
)
for e in auth_chain:
e.internal_metadata.outlier = True
try:
yield self._handle_new_event(origin, e)
except:
logger.exception(
"Failed to handle auth event %s",
e.event_id,
)
current_state = state current_state = state
if state: if state and auth_chain is not None:
for e in state: for e in state:
e.internal_metadata.outlier = True e.internal_metadata.outlier = True
try: try:
yield self._handle_new_event(origin, e) auth_ids = [e_id for e_id, _ in e.auth_events]
auth = {
(e.type, e.state_key): e for e in auth_chain
if e.event_id in auth_ids
}
yield self._handle_new_event(origin, e, auth_events=auth)
except: except:
logger.exception( logger.exception(
"Failed to handle state event %s", "Failed to handle state event %s",
@ -809,18 +789,23 @@ class FederationHandler(BaseHandler):
) )
# 3. Process any remote auth chain events we haven't seen. # 3. Process any remote auth chain events we haven't seen.
for e in result.get("missing", []): for missing_id in result.get("missing", []):
try: try:
auth_ids = [e_id for e_id, _ in e.auth_events] for e in result["auth_chain"]:
if e.event_id == missing_id:
ev = e
break
auth_ids = [e_id for e_id, _ in ev.auth_events]
auth = { auth = {
(e.type, e.state_key): e for e in result["auth_chain"] (e.type, e.state_key): e for e in result["auth_chain"]
if e.event_id in auth_ids if e.event_id in auth_ids
} }
e.internal_metadata.outlier = True ev.internal_metadata.outlier = True
yield self._handle_new_event( yield self._handle_new_event(
origin, e, auth_events=auth origin, ev, auth_events=auth
) )
auth_events[(e.type, e.state_key)] = e auth_events[(ev.type, ev.state_key)] = ev
except AuthError: except AuthError:
pass pass
@ -970,5 +955,5 @@ class FederationHandler(BaseHandler):
} }
for e in base_remote_rejected for e in base_remote_rejected
}, },
"missing": missing_locals, "missing": [e.event_id for e in missing_locals],
}) })

View file

@ -166,10 +166,17 @@ class StateHandler(object):
first is the name of a state group if one and only one is involved, first is the name of a state group if one and only one is involved,
otherwise `None`. otherwise `None`.
""" """
logger.debug("resolve_state_groups event_ids %s", event_ids)
state_groups = yield self.store.get_state_groups( state_groups = yield self.store.get_state_groups(
event_ids event_ids
) )
logger.debug(
"resolve_state_groups state_groups %s",
state_groups.keys()
)
group_names = set(state_groups.keys()) group_names = set(state_groups.keys())
if len(group_names) == 1: if len(group_names) == 1:
name, state_list = state_groups.items().pop() name, state_list = state_groups.items().pop()
@ -205,6 +212,15 @@ class StateHandler(object):
if len(v.values()) > 1 if len(v.values()) > 1
} }
logger.debug(
"resolve_state_groups Unconflicted state: %s",
unconflicted_state.values(),
)
logger.debug(
"resolve_state_groups Conflicted state: %s",
conflicted_state.values(),
)
if event_type: if event_type:
prev_states_events = conflicted_state.get( prev_states_events = conflicted_state.get(
(event_type, state_key), [] (event_type, state_key), []
@ -240,10 +256,6 @@ class StateHandler(object):
1. power levels 1. power levels
2. memberships 2. memberships
3. other events. 3. other events.
:param conflicted_state:
:param auth_events:
:return:
""" """
resolved_state = {} resolved_state = {}
power_key = (EventTypes.PowerLevels, "") power_key = (EventTypes.PowerLevels, "")