summary refs log tree commit diff
diff options
context:
space:
mode:
authorEric Eastwood <erice@element.io>2022-08-30 14:50:06 -0500
committerGitHub <noreply@github.com>2022-08-30 14:50:06 -0500
commit92c5817e34cb421dbe2c0df275238e84866932a8 (patch)
tree7a618d1fc8c949074bb05f9113ceb4e6e5242866
parentDrop unused column `application_services_state.last_txn` (#13627) (diff)
downloadsynapse-92c5817e34cb421dbe2c0df275238e84866932a8.tar.xz
Give the correct next event when the message timestamps are the same - MSC3030 (#13658)
Discovered while working on https://github.com/matrix-org/synapse/pull/13589 and I had all the messages at the same timestamp in the tests.

Part of https://github.com/matrix-org/matrix-spec-proposals/pull/3030

Complement tests: https://github.com/matrix-org/complement/pull/457
-rw-r--r--changelog.d/13658.bugfix1
-rw-r--r--synapse/storage/databases/main/events_worker.py12
2 files changed, 11 insertions, 2 deletions
diff --git a/changelog.d/13658.bugfix b/changelog.d/13658.bugfix
new file mode 100644
index 0000000000..8740f066bb
--- /dev/null
+++ b/changelog.d/13658.bugfix
@@ -0,0 +1 @@
+Fix MSC3030 `/timestamp_to_event` endpoint to return the correct next event when the events have the same timestamp.
diff --git a/synapse/storage/databases/main/events_worker.py b/synapse/storage/databases/main/events_worker.py
index 8a7cdb024d..9b997c304d 100644
--- a/synapse/storage/databases/main/events_worker.py
+++ b/synapse/storage/databases/main/events_worker.py
@@ -2111,7 +2111,14 @@ class EventsWorkerStore(SQLBaseStore):
                 AND room_id = ?
                 /* Make sure event is not rejected */
                 AND rejections.event_id IS NULL
-            ORDER BY origin_server_ts %s
+            /**
+             * First sort by the message timestamp. If the message timestamps are the
+             * same, we want the message that logically comes "next" (before/after
+             * the given timestamp) based on the DAG and its topological order (`depth`).
+             * Finally, we can tie-break based on when it was received on the server
+             * (`stream_ordering`).
+             */
+            ORDER BY origin_server_ts %s, depth %s, stream_ordering %s
             LIMIT 1;
         """
 
@@ -2130,7 +2137,8 @@ class EventsWorkerStore(SQLBaseStore):
                 order = "ASC"
 
             txn.execute(
-                sql_template % (comparison_operator, order), (timestamp, room_id)
+                sql_template % (comparison_operator, order, order, order),
+                (timestamp, room_id),
             )
             row = txn.fetchone()
             if row: