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

Commit

Permalink
Add some clarifying comments and refactor a portion of the Keyring
Browse files Browse the repository at this point in the history
…class for readability (#14804)
  • Loading branch information
anoadragon453 authored Jan 13, 2023
1 parent 772e8c2 commit 3a12562
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 18 deletions.
1 change: 1 addition & 0 deletions changelog.d/14804.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add some clarifying comments and refactor a portion of the `Keyring` class for readability.
61 changes: 43 additions & 18 deletions synapse/crypto/keyring.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,17 +154,21 @@ def __init__(

if key_fetchers is None:
key_fetchers = (
# Fetch keys from the database.
StoreKeyFetcher(hs),
# Fetch keys from a configured Perspectives server.
PerspectivesKeyFetcher(hs),
# Fetch keys from the origin server directly.
ServerKeyFetcher(hs),
)
self._key_fetchers = key_fetchers

self._server_queue: BatchingQueue[
self._fetch_keys_queue: BatchingQueue[
_FetchKeyRequest, Dict[str, Dict[str, FetchKeyResult]]
] = BatchingQueue(
"keyring_server",
clock=hs.get_clock(),
# The method called to fetch each key
process_batch_callback=self._inner_fetch_key_requests,
)

Expand Down Expand Up @@ -287,7 +291,7 @@ async def process_request(self, verify_request: VerifyJsonRequest) -> None:
minimum_valid_until_ts=verify_request.minimum_valid_until_ts,
key_ids=list(key_ids_to_find),
)
found_keys_by_server = await self._server_queue.add_to_queue(
found_keys_by_server = await self._fetch_keys_queue.add_to_queue(
key_request, key=verify_request.server_name
)

Expand Down Expand Up @@ -352,7 +356,17 @@ async def _process_json(
async def _inner_fetch_key_requests(
self, requests: List[_FetchKeyRequest]
) -> Dict[str, Dict[str, FetchKeyResult]]:
"""Processing function for the queue of `_FetchKeyRequest`."""
"""Processing function for the queue of `_FetchKeyRequest`.
Takes a list of key fetch requests, de-duplicates them and then carries out
each request by invoking self._inner_fetch_key_request.
Args:
requests: A list of requests for homeserver verify keys.
Returns:
{server name: {key id: fetch key result}}
"""

logger.debug("Starting fetch for %s", requests)

Expand Down Expand Up @@ -397,8 +411,23 @@ async def _inner_fetch_key_requests(
async def _inner_fetch_key_request(
self, verify_request: _FetchKeyRequest
) -> Dict[str, FetchKeyResult]:
"""Attempt to fetch the given key by calling each key fetcher one by
one.
"""Attempt to fetch the given key by calling each key fetcher one by one.
If a key is found, check whether its `valid_until_ts` attribute satisfies the
`minimum_valid_until_ts` attribute of the `verify_request`. If it does, we
refrain from asking subsequent fetchers for that key.
Even if the above check fails, we still return the found key - the caller may
still find the invalid key result useful. In this case, we continue to ask
subsequent fetchers for the invalid key, in case they return a valid result
for it. This can happen when fetching a stale key result from the database,
before querying the origin server for an up-to-date result.
Args:
verify_request: The request for a verify key. Can include multiple key IDs.
Returns:
A map of {key_id: the key fetch result}.
"""
logger.debug("Starting fetch for %s", verify_request)

Expand All @@ -420,26 +449,22 @@ async def _inner_fetch_key_request(
if not key:
continue

# If we already have a result for the given key ID we keep the
# If we already have a result for the given key ID, we keep the
# one with the highest `valid_until_ts`.
existing_key = found_keys.get(key_id)
if existing_key:
if key.valid_until_ts <= existing_key.valid_until_ts:
continue
if existing_key and existing_key.valid_until_ts > key.valid_until_ts:
continue

# Check if this key's expiry timestamp is valid for the verify request.
if key.valid_until_ts >= verify_request.minimum_valid_until_ts:
# Stop looking for this key from subsequent fetchers.
missing_key_ids.discard(key_id)

# We always store the returned key even if it doesn't the
# We always store the returned key even if it doesn't meet the
# `minimum_valid_until_ts` requirement, as some verification
# requests may still be able to be satisfied by it.
#
# We still keep looking for the key from other fetchers in that
# case though.
found_keys[key_id] = key

if key.valid_until_ts < verify_request.minimum_valid_until_ts:
continue

missing_key_ids.discard(key_id)

return found_keys


Expand Down

0 comments on commit 3a12562

Please sign in to comment.