Skip to content

Conversation

kaylendog
Copy link
Contributor

@kaylendog kaylendog commented Jul 28, 2025

Implements support for encrypted state events under m.room.encrypted, as outlined in MSC3414.

  • (base) Modifies state_events::sync::dispatch to require E2EE when end-to-end encryption is enabled, using it to decrypt m.room.encrypted state events when received.
  • (base) Declares m.room.encrypted as required state by default.
  • (crypto) Introduces encrypt_state_event and encrypt_state_event_raw to OlmMachine and OutboundGroupSession;
  • (sdk) Modifies Room::send_state_event and Room::send_state_event_Raw to return SendStateEvent and SendStateEventRaw futures respectifely, that each function similarly to their message-like counterparts.
  • (integration) Add an integration test for encrypted room renaming.

@kaylendog kaylendog requested review from a team as code owners July 28, 2025 15:06
@kaylendog kaylendog requested review from bnjbvr and richvdh and removed request for a team July 28, 2025 15:06
@kaylendog kaylendog marked this pull request as draft July 28, 2025 15:06
@kaylendog kaylendog self-assigned this Jul 28, 2025
@bnjbvr bnjbvr requested review from a team and poljar and removed request for bnjbvr July 28, 2025 15:07
@richvdh
Copy link
Member

richvdh commented Jul 28, 2025

This is part of #5397

@kaylendog kaylendog force-pushed the kaylendog/encrypted-state-events-compat branch 2 times, most recently from 79697a3 to 93feb08 Compare July 30, 2025 13:25
Copy link

codspeed-hq bot commented Jul 30, 2025

CodSpeed Performance Report

Merging #5456 will not alter performance

Comparing kaylendog:kaylendog/encrypted-state-events-compat (61d40bd) with main (669ebf2)

Summary

✅ 31 untouched benchmarks

@kaylendog kaylendog force-pushed the kaylendog/encrypted-state-events-compat branch from 9dddf23 to 3dec91a Compare July 31, 2025 15:16
@zecakeh
Copy link
Collaborator

zecakeh commented Aug 1, 2025

For information, #5473 upgrades Ruma and brings in the encrypted state events changes.

@kaylendog kaylendog force-pushed the kaylendog/encrypted-state-events-compat branch from 3dec91a to ee6a293 Compare August 4, 2025 11:42
@richvdh richvdh removed their request for review August 4, 2025 16:28
Copy link

codecov bot commented Aug 4, 2025

Codecov Report

❌ Patch coverage is 80.78818% with 39 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.56%. Comparing base (669ebf2) to head (a8b7d11).
⚠️ Report is 16 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
crates/matrix-sdk/src/room/futures.rs 79.43% 13 Missing and 9 partials ⚠️
crates/matrix-sdk-crypto/src/machine/mod.rs 44.44% 15 Missing ⚠️
...k-crypto/src/session_manager/group_sessions/mod.rs 87.50% 0 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5456      +/-   ##
==========================================
- Coverage   88.57%   88.56%   -0.01%     
==========================================
  Files         339      339              
  Lines       93603    93800     +197     
  Branches    93603    93800     +197     
==========================================
+ Hits        82910    83078     +168     
- Misses       6560     6577      +17     
- Partials     4133     4145      +12     

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

@kaylendog kaylendog force-pushed the kaylendog/encrypted-state-events-compat branch from 4882f4e to 5cb4dd9 Compare August 5, 2025 12:10
@kaylendog kaylendog marked this pull request as ready for review August 5, 2025 12:16
@richvdh richvdh self-requested a review August 5, 2025 12:57
@kaylendog kaylendog force-pushed the kaylendog/encrypted-state-events-compat branch 3 times, most recently from 2c93f9f to 6c49a11 Compare August 6, 2025 16:41
@kaylendog kaylendog force-pushed the kaylendog/encrypted-state-events-compat branch 3 times, most recently from 00c3e99 to b060f96 Compare August 7, 2025 10:57
@kaylendog kaylendog force-pushed the kaylendog/encrypted-state-events-compat branch from b060f96 to 61d40bd Compare August 7, 2025 14:34
Copy link
Member

@richvdh richvdh left a comment

Choose a reason for hiding this comment

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

General comments:

  • Yay! excites! It generally looks very sensible.

  • I wonder if all this functionality should be behind compile-time cfg guards, since it's entirely unspecced. @poljar: any thoughts on this?

  • For future reference: your commit comments could do with a little more detail. Try and explain how the bit of functionality that bit introduces fits in with the whole.

  • Before this is ready to land in the rust SDK, I think we need some more (or, indeed, any) unit tests, which exercise individual parts of the functionality without rolling it into a big integration test.

    For sure an integration test is nice to make sure it all works as a whole, but integration tests are slooow and make it painful to figure out which bit of the code is misbehaving. Plus, unit tests make it easier to exercise the non-happy paths since you can mock out the homeserver. Codecov is having one of its "special" days, but when it recovers I'd expect it to complain about lack of code coverage. There's a concept called the Test Pyramid which says you should have lots of low-level tests and a few high-level tests.

    (Generally, I'd expect to see code, and unit tests that exercise that code, landing in the same commit.)

  • We should be able to break this PR into smaller chunks, especially if we have more tests. Smaller PRs are generally a good thing since it means that author and reviewer have less state to keep in their head as the PR goes through multiple rounds of review. (Some guy called richvdh wrote a blog post mentioning this.)

///
/// # Panics
///
/// Panics if no such session exists for the given room ID, or the session
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
/// Panics if no such session exists for the given room ID, or the session
/// Panics if no session exists for the given room ID, or the session

Comment on lines +1141 to +1147
/// * `room_id` - The id of the room for which the message should be
/// encrypted.
///
/// * `content` - The plaintext content of the event that should be
/// encrypted as a raw JSON value.
///
/// * `state_key` - The associated state key of the event.
Copy link
Member

Choose a reason for hiding this comment

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

event_type is missing here, and the order is inconsistent with the actual arguments

@@ -319,3 +321,83 @@ impl<'a> IntoFuture for SendAttachment<'a> {
Box::pin(fut.instrument(tracing_span))
}
}

/// TODO: Future returned by `Room::send_state_event_raw`.
Copy link
Member

Choose a reason for hiding this comment

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

what does this TODO mean?


/// TODO: Future returned by `Room::send_state_event_raw`.
#[allow(missing_debug_implementations)]
pub struct SendStateEventRaw<'a> {
Copy link
Member

Choose a reason for hiding this comment

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

🤔 I wonder if this should be called sendRawStateLikeEvent for consistency with SendRawMessageLikeEvent.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was going for consistency with Ruma - it uses StateEvent and MessageLikeEvent.

Copy link
Collaborator

Choose a reason for hiding this comment

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

(and Ruma uses "message-like" to disambiguate from m.room.message / m.message)

let content =
deserialized_event.original_content().expect("The event should not have been redacted");

assert_matches2::assert_let!($pat = content);
Copy link
Member

Choose a reason for hiding this comment

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

Looks like you've forgotten to use $msg here.

Comment on lines +269 to +270
/// Given a [`TimelineEvent`], assert that the event is a decrypted state
/// event, and that its content matches the given pattern via a let binding.
Copy link
Member

Choose a reason for hiding this comment

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

Some examples might help me understand how to use this.

/// event, and that its content matches the given pattern via a let binding.
#[macro_export]
macro_rules! assert_let_decrypted_state_event_content {
($pat:pat = $event:expr, $($msg:tt)*) => {
Copy link
Member

Choose a reason for hiding this comment

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

The documentation could do with mentioning that the macro uses the second and subsequent arguments, if provided, as an error message if the content does not match.

Comment on lines +64 to +65
// HACK: wait for sync
let _ = tokio::time::sleep(Duration::from_secs(3)).await;
Copy link
Member

Choose a reason for hiding this comment

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

We need to find something to wait for, rather than just sleeping for 3 seconds. There's a wait_until_some helper which I imagine you could combine with is_state_encrypted to do what you need.

Copy link
Member

Choose a reason for hiding this comment

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

that said... didn't we agree this was a bug in enable_encryption[_with_state] which should be fixed in a separate PR?

Comment on lines +414 to +415
/// Whether state event encryption is enabled.
pub encrypt_state_events: bool,
Copy link
Member

Choose a reason for hiding this comment

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

RoomSettings is serialized and persisted in clients' local stores. We'll need to make sure it behaves sensibly when the serialized version omits the field. (In other words, needs #[serde(default)] or something)

The commit comment is a bit weird too: it says "WASM SDK" but ... this isn't the wasm bindings project.

TBH I'd suggest pulling this RoomSettings stuff out to a separate PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I included WASM SDK in the commit message since this change (afaik) will only affect it and not the rest of the Rust SDK, since it uses the m.room.encryption event to decide whether to encrypt rather than this - I can change?

Copy link
Member

Choose a reason for hiding this comment

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

I think this probably just falls into the more general bracket of "your commit comments could do with a little more detail". You're allowed to use more than one line ;)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have pulled this out to #5511 - I'll drop the commit that introduces this after our meeting.

Copy link

codspeed-hq bot commented Aug 8, 2025

Unable to generate the performance report

There was an internal error while processing the run's data. We're working on fixing the issue. Feel free to contact us on Discord or at [email protected] if the issue persists.

@kaylendog
Copy link
Contributor Author

kaylendog commented Aug 12, 2025

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.

4 participants