Skip to content

Conversation

@Hywan
Copy link
Member

@Hywan Hywan commented Sep 3, 2025

This set of patches updates the room list to sort rooms by their “latest event”. What does it mean?

  • We want a room with a local latest event to be at the top of the room list,
  • We want a room to have an accurate position in the room list, which means we want to rely on the latest event instead of the room recency_stamp (also known as the bump_stamp in sliding sync terminology):
    • Why was recency_stamp inaccurate? Because the server might bump a room based on certain events, so the room will bump in the room list, but the latest event won't change because the event causing the bump is not a latest event candidate. Because the latest event is used by som apps to display the room “last updated time” in the room, the user might see unordered rooms!
    • One may argue that we should keep the list of events triggering a bump on the server in-sync with the list of latest event candidates on the client side. I would happily counter-argue that it's server-dependent and client-dependent. Not all servers and not all clients want the same behaviour. The list on the server is “best-effort”. Also, it's not configurable anymore with Simplified Sliding Sync (MSC4186).
    • One may also argue that sorting by latest event's timestamp means we use the famous origin_server_rs value, which is a mistake because it can be forged by malicious servers! Yes, that's true, but:
      • There is no security risk involved here. At worst, a room is sticked at the top or the bottom of the room list, that's it.
      • We were using this value in the past and we agreed it was fine (happy to re-discuss that if needed).
      • Some homeservers can use the origin_server_ts value of the last event in the room as the value for bump_stamp. We can't control this, it's an opaque value.

All-in-all, this set of patches creates a new latest_event sorter for the room list. Then it updates the recency sorter to be “latest-event aware”. Finally, it installs the new latest_event sorter.


@codecov
Copy link

codecov bot commented Sep 3, 2025

Codecov Report

❌ Patch coverage is 96.33205% with 19 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.93%. Comparing base (441b006) to head (d9db53e).
⚠️ Report is 11 commits behind head on main.

Files with missing lines Patch % Lines
.../room_list_service/filters/deduplicate_versions.rs 81.25% 6 Missing ⚠️
...x-sdk-ui/src/room_list_service/filters/category.rs 87.50% 2 Missing ⚠️
...rix-sdk-ui/src/room_list_service/filters/invite.rs 71.42% 2 Missing ⚠️
...rix-sdk-ui/src/room_list_service/filters/joined.rs 71.42% 2 Missing ⚠️
...k-ui/src/room_list_service/filters/low_priority.rs 66.66% 2 Missing ⚠️
...trix-sdk-ui/src/room_list_service/filters/space.rs 66.66% 2 Missing ⚠️
...rix-sdk-ui/src/room_list_service/filters/unread.rs 92.85% 2 Missing ⚠️
...-sdk-ui/src/room_list_service/filters/favourite.rs 80.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5617      +/-   ##
==========================================
+ Coverage   88.89%   88.93%   +0.04%     
==========================================
  Files         349      350       +1     
  Lines       96546    96854     +308     
  Branches    96546    96854     +308     
==========================================
+ Hits        85826    86140     +314     
+ Misses       6682     6676       -6     
  Partials     4038     4038              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@codspeed-hq
Copy link

codspeed-hq bot commented Sep 3, 2025

CodSpeed Performance Report

Merging #5617 will not alter performance

Comparing Hywan:feat-ui-latest-events-sorter (d9db53e) with main (441b006)

Summary

✅ 49 untouched benchmarks

@Hywan Hywan force-pushed the feat-ui-latest-events-sorter branch 5 times, most recently from 5800753 to d163d1c Compare September 3, 2025 13:03
@Hywan Hywan marked this pull request as ready for review September 3, 2025 13:32
@Hywan Hywan requested a review from a team as a code owner September 3, 2025 13:32
@Hywan Hywan requested review from poljar and removed request for a team September 3, 2025 13:32
Copy link
Contributor

@poljar poljar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of it makes sense and thanks for the comprehensive test suite.

I left some questions and recommendations that I think make sense.

/// Get the timestamp of the [`LatestEventValue`].
///
/// If it's [`None`], it returns `None`. If it's [`Remote`], it returns the
/// `origin_server_ts`. If it's [`LocalIsSending`] or [`LocalCannotBeSent`],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We discussed this in chat but the discussion died down, so I'll repeat here.

To avoid malicious homeservers and users manipulating our room ordering using the origin_server_ts can't we record a local timestamp whenever we create a new LatestEventValue?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. I've been thinking about that.

When we receive an event via the sync, we can record the now() as the local timestamp. However, it means that all events from all rooms for a particular sync will have the same local timestamp, and thus, we can't use that to sort the rooms (because all “recorded timestamps” will be equal).

I think we have to keep origin_server_ts for the moment. We can warn it's a known limitations. It's also used to display the event's time in the timeline for example. If we can't trust this value, it's a protocol issue I suppose. I don't see how to solve that for the moment.

@Hywan Hywan requested a review from poljar September 9, 2025 07:19
@Hywan Hywan force-pushed the feat-ui-latest-events-sorter branch 3 times, most recently from f09d0ea to 127f677 Compare September 9, 2025 07:23
Copy link
Contributor

@poljar poljar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, looks good.

There's still the question of using origin_server_ts exclusively for this, but as you said, this can be a separate PR.

Hywan added 11 commits September 9, 2025 15:27
This patch implements the new `latest_event` sorter for the room list
which puts the local latest events before the other kinds (like `Remote`
or `None`).
This patch implements a `LatestEventValue::timestamp` method to fetch
the timestamp of a latest event value.
This patch updates the `recency` sorter of the room list to rely on the
`LatestEventValue`'s timestamp, or on the `bump_stamp` returned by the
sync. Using the `LatestEventValue`'s timestamp is more reliable as we
don't rely on the server. However, we must be careful to compare values
of the same nature because the timetamp from the `LatestEventValue` and
the `bump_stamp` doesn't represent the same thing! The `bump_stamp` is
only used when the value for the `LatestEventValue` is `None`.

It's a compromise to get a more accurate listing. Though,
`LatestEventValue::timestamp` returns the `origin_server_ts` value,
which can be forged by a malicious user (then a room could be _sticked_
at the top or at the bottom of the room list). Note that this problem
already existed in the past before the server computed a `bump_stamp`.
Also note that some homeservers use the `origin_server_ts` as the
`bump_stamp` value. Anyway, it's not a security risk as far as I know.
This patch installs the `new_sorter_latest_event` in the room list.
This patch adds the `RoomRecencyStamp` type to avoid confusion with other
`u64` values.
…orters`.

This patch renames all the structure `*Matcher` to `*Sorter`.
And their `matches` method become `cmp`. It was copy-pasted from
`room_list_service::filters` probably, but the semantics here are not
_matcher_ but _sorter_. It's more consistent that `cmp` returns an
`Ordering`.
This patch adds the notion of _rank_ in the `recency` sorter to avoid
confusion around `u64`: is it a timestamp or a recency stamp? It's
purely semantics, but I hope it clarify the code.
This patch removes intermediate structs and uses a function directly.
This patch removes intermediate structs and uses a function directly.
@Hywan Hywan force-pushed the feat-ui-latest-events-sorter branch from 590c075 to d9db53e Compare September 9, 2025 13:27
@Hywan Hywan enabled auto-merge (rebase) September 9, 2025 13:29
@Hywan Hywan merged commit 5c78dde into matrix-org:main Sep 9, 2025
52 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants