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

Remove fallback for missing /federation/v1/state_ids API #6488

Merged
merged 1 commit into from
Dec 9, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/6488.removal
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Remove fallback for federation with old servers which lack the /federation/v1/state_ids API.
89 changes: 17 additions & 72 deletions synapse/federation/federation_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -324,87 +324,32 @@ def get_state_for_room(self, destination, room_id, event_id):
A list of events in the state, and a list of events in the auth chain
for the given event.
"""
try:
# First we try and ask for just the IDs, as thats far quicker if
# we have most of the state and auth_chain already.
# However, this may 404 if the other side has an old synapse.
result = yield self.transport_layer.get_room_state_ids(
destination, room_id, event_id=event_id
)

state_event_ids = result["pdu_ids"]
auth_event_ids = result.get("auth_chain_ids", [])

fetched_events, failed_to_fetch = yield self.get_events_from_store_or_dest(
destination, room_id, set(state_event_ids + auth_event_ids)
)

if failed_to_fetch:
logger.warning(
"Failed to fetch missing state/auth events for %s: %s",
room_id,
failed_to_fetch,
)

event_map = {ev.event_id: ev for ev in fetched_events}

pdus = [event_map[e_id] for e_id in state_event_ids if e_id in event_map]
auth_chain = [
event_map[e_id] for e_id in auth_event_ids if e_id in event_map
]

auth_chain.sort(key=lambda e: e.depth)

return pdus, auth_chain
except HttpResponseException as e:
if e.code == 400 or e.code == 404:
logger.info("Failed to use get_room_state_ids API, falling back")
else:
raise e

result = yield self.transport_layer.get_room_state(
result = yield self.transport_layer.get_room_state_ids(
destination, room_id, event_id=event_id
)

room_version = yield self.store.get_room_version(room_id)
format_ver = room_version_to_event_format(room_version)

pdus = [
event_from_pdu_json(p, format_ver, outlier=True) for p in result["pdus"]
]
state_event_ids = result["pdu_ids"]
auth_event_ids = result.get("auth_chain_ids", [])

auth_chain = [
event_from_pdu_json(p, format_ver, outlier=True)
for p in result.get("auth_chain", [])
]

seen_events = yield self.store.get_events(
[ev.event_id for ev in itertools.chain(pdus, auth_chain)]
fetched_events, failed_to_fetch = yield self.get_events_from_store_or_dest(
destination, room_id, set(state_event_ids + auth_event_ids)
)

signed_pdus = yield self._check_sigs_and_hash_and_fetch(
destination,
[p for p in pdus if p.event_id not in seen_events],
outlier=True,
room_version=room_version,
)
signed_pdus.extend(
seen_events[p.event_id] for p in pdus if p.event_id in seen_events
)
if failed_to_fetch:
logger.warning(
"Failed to fetch missing state/auth events for %s: %s",
room_id,
failed_to_fetch,
)

signed_auth = yield self._check_sigs_and_hash_and_fetch(
destination,
[p for p in auth_chain if p.event_id not in seen_events],
outlier=True,
room_version=room_version,
)
signed_auth.extend(
seen_events[p.event_id] for p in auth_chain if p.event_id in seen_events
)
event_map = {ev.event_id: ev for ev in fetched_events}

signed_auth.sort(key=lambda e: e.depth)
pdus = [event_map[e_id] for e_id in state_event_ids if e_id in event_map]
auth_chain = [event_map[e_id] for e_id in auth_event_ids if e_id in event_map]

auth_chain.sort(key=lambda e: e.depth)

return signed_pdus, signed_auth
return pdus, auth_chain

@defer.inlineCallbacks
def get_events_from_store_or_dest(self, destination, room_id, event_ids):
Expand Down
24 changes: 0 additions & 24 deletions synapse/federation/transport/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,30 +38,6 @@ def __init__(self, hs):
self.server_name = hs.hostname
self.client = hs.get_http_client()

@log_function
def get_room_state(self, destination, room_id, event_id):
""" Requests all state for a given room from the given server at the
given event.

Args:
destination (str): The host name of the remote homeserver we want
to get the state from.
context (str): The name of the context we want the state of
event_id (str): The event we want the context at.

Returns:
Deferred: Results in a dict received from the remote homeserver.
"""
logger.debug("get_room_state dest=%s, room=%s", destination, room_id)

path = _create_v1_path("/state/%s", room_id)
return self.client.get_json(
destination,
path=path,
args={"event_id": event_id},
try_trailing_slash_on_400=True,
)

@log_function
def get_room_state_ids(self, destination, room_id, event_id):
""" Requests all state for a given room from the given server at the
Expand Down