summary refs log tree commit diff
path: root/synapse
diff options
context:
space:
mode:
authorErik Johnston <erikj@matrix.org>2023-09-05 20:27:41 +0100
committerGitHub <noreply@github.com>2023-09-05 20:27:41 +0100
commitc9cec2daed00406b5337a8ce7064e3394ceaf656 (patch)
tree107f8336db9dc8268b84661095e9aa7dfca2b9d9 /synapse
parentMerge tag 'v1.92.0rc1' into develop (diff)
downloadsynapse-c9cec2daed00406b5337a8ce7064e3394ceaf656.tar.xz
Fix bug where we kept re-requesting a remote server's key repeatedly. (#16257)
* Correctly handle multiple rows per server/key

* Newsfile
Diffstat (limited to 'synapse')
-rw-r--r--synapse/storage/databases/main/keys.py17
1 files changed, 11 insertions, 6 deletions
diff --git a/synapse/storage/databases/main/keys.py b/synapse/storage/databases/main/keys.py
index a3b4744855..57aa4921e1 100644
--- a/synapse/storage/databases/main/keys.py
+++ b/synapse/storage/databases/main/keys.py
@@ -221,12 +221,17 @@ class KeyStore(CacheInvalidationWorkerStore):
             """Processes a batch of keys to fetch, and adds the result to `keys`."""
 
             # batch_iter always returns tuples so it's safe to do len(batch)
-            sql = """
-            SELECT server_name, key_id, key_json, ts_valid_until_ms
-            FROM server_keys_json WHERE 1=0
-            """ + " OR (server_name=? AND key_id=?)" * len(
-                batch
-            )
+            where_clause = " OR (server_name=? AND key_id=?)" * len(batch)
+
+            # `server_keys_json` can have multiple entries per server (one per
+            # remote server we fetched from, if using perspectives). Order by
+            # `ts_added_ms` so the most recently fetched one always wins.
+            sql = f"""
+                SELECT server_name, key_id, key_json, ts_valid_until_ms
+                FROM server_keys_json WHERE 1=0
+                {where_clause}
+                ORDER BY ts_added_ms
+            """
 
             txn.execute(sql, tuple(itertools.chain.from_iterable(batch)))