Fix "unhashable type: 'list'" exception in federation handling

get_state_groups returns a map from state_group_id to a list of FrozenEvents,
so was very much the wrong thing to be putting as one of the entries in the
list passed to resolve_events_with_factory (which expects maps from
(event_type, state_key) to event id).

We actually want get_state_groups_ids().values() rather than
get_state_groups().

This fixes the main problem in #3923, but there are other problems with this
bit of code which get discovered once you do so.
This commit is contained in:
Richard van der Hoff 2018-09-26 09:52:56 +01:00
parent 28223841e0
commit a215b698c4

View file

@ -106,7 +106,7 @@ class FederationHandler(BaseHandler):
self.hs = hs self.hs = hs
self.store = hs.get_datastore() self.store = hs.get_datastore() # type: synapse.storage.DataStore
self.federation_client = hs.get_federation_client() self.federation_client = hs.get_federation_client()
self.state_handler = hs.get_state_handler() self.state_handler = hs.get_state_handler()
self.server_name = hs.hostname self.server_name = hs.hostname
@ -325,12 +325,17 @@ class FederationHandler(BaseHandler):
# Calculate the state of the previous events, and # Calculate the state of the previous events, and
# de-conflict them to find the current state. # de-conflict them to find the current state.
state_groups = []
auth_chains = set() auth_chains = set()
try: try:
# Get the state of the events we know about # Get the state of the events we know about
ours = yield self.store.get_state_groups(room_id, list(seen)) ours = yield self.store.get_state_groups_ids(room_id, seen)
state_groups.append(ours)
# state_maps is a list of mappings from (type, state_key) to event_id
# type: list[dict[tuple[str, str], str]]
state_maps = list(ours.values())
# we don't need this any more, let's delete it.
del ours
# Ask the remote server for the states we don't # Ask the remote server for the states we don't
# know about # know about
@ -355,10 +360,10 @@ class FederationHandler(BaseHandler):
# hoped. # hoped.
auth_chains.update(got_auth_chain) auth_chains.update(got_auth_chain)
state_group = { remote_state_map = {
(x.type, x.state_key): x.event_id for x in remote_state (x.type, x.state_key): x.event_id for x in remote_state
} }
state_groups.append(state_group) state_maps.append(remote_state_map)
# Resolve any conflicting state # Resolve any conflicting state
def fetch(ev_ids): def fetch(ev_ids):
@ -368,7 +373,7 @@ class FederationHandler(BaseHandler):
room_version = yield self.store.get_room_version(room_id) room_version = yield self.store.get_room_version(room_id)
state_map = yield resolve_events_with_factory( state_map = yield resolve_events_with_factory(
room_version, state_groups, {event_id: pdu}, fetch room_version, state_maps, {event_id: pdu}, fetch,
) )
state = (yield self.store.get_events(state_map.values())).values() state = (yield self.store.get_events(state_map.values())).values()