From 51ff8ee3d6a5b71cd5f6cd15de372590294375e6 Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Thu, 4 Jun 2026 11:31:45 -0500 Subject: [PATCH] Refine usage --- rust/src/config/mod.rs | 35 +++ rust/src/handlers/mod.rs | 42 ++++ rust/src/handlers/versions.rs | 246 ++++++++++---------- rust/src/lib.rs | 5 +- rust/src/{ => storage}/db/db.rs | 0 rust/src/{ => storage}/db/mod.rs | 0 rust/src/{ => storage}/db/python_db_pool.rs | 0 rust/src/storage/mod.rs | 17 ++ rust/src/storage/store.rs | 29 +++ synapse/storage/util/id_generators.py | 2 + 10 files changed, 258 insertions(+), 118 deletions(-) create mode 100644 rust/src/config/mod.rs create mode 100644 rust/src/handlers/mod.rs rename rust/src/{ => storage}/db/db.rs (100%) rename rust/src/{ => storage}/db/mod.rs (100%) rename rust/src/{ => storage}/db/python_db_pool.rs (100%) create mode 100644 rust/src/storage/mod.rs create mode 100644 rust/src/storage/store.rs diff --git a/rust/src/config/mod.rs b/rust/src/config/mod.rs new file mode 100644 index 0000000000..af7ccee1aa --- /dev/null +++ b/rust/src/config/mod.rs @@ -0,0 +1,35 @@ +/* + * This file is licensed under the Affero General Public License (AGPL) version 3. + * + * Copyright (C) 2026 Element Creations Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * See the GNU Affero General Public License for more details: + * . + * + */ + +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct SynapseConfig { + pub experimental: ExperimentalConfig, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +#[serde(rename_all = "snake_case")] +pub enum RoomCreationPreset { + PrviateChat, + PublicChat, + TrustedPrivateChat, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ExperimentalConfig { + pub msc3881_enabled: bool, + pub msc3575_enabled: bool, +} diff --git a/rust/src/handlers/mod.rs b/rust/src/handlers/mod.rs new file mode 100644 index 0000000000..559dd809b5 --- /dev/null +++ b/rust/src/handlers/mod.rs @@ -0,0 +1,42 @@ +/* + * This file is licensed under the Affero General Public License (AGPL) version 3. + * + * Copyright (C) 2026 Element Creations Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * See the GNU Affero General Public License for more details: + * . + * + */ + +use pyo3::{ + types::{PyAnyMethods, PyModule, PyModuleMethods}, + wrap_pyfunction, Bound, PyResult, Python, +}; +use serde::{Deserialize, Serialize}; + +pub mod versions; + +/// Called when registering modules with python. +pub fn register_module(py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> { + let child_module = PyModule::new(py, "handlers")?; + child_module.add_class::()?; + child_module.add_class::()?; + child_module.add_class::()?; + child_module.add_class::()?; + child_module.add_function(wrap_pyfunction!(get_base_rule_ids, m)?)?; + + m.add_submodule(&child_module)?; + + // We need to manually add the module to sys.modules to make `from + // synapse.synapse_rust import push` work. + py.import("sys")? + .getattr("modules")? + .set_item("synapse.synapse_rust.handlers", child_module)?; + + Ok(()) +} diff --git a/rust/src/handlers/versions.rs b/rust/src/handlers/versions.rs index 6f1d4ffe6a..6d8493b141 100644 --- a/rust/src/handlers/versions.rs +++ b/rust/src/handlers/versions.rs @@ -1,4 +1,3 @@ - /* * This file is licensed under the Affero General Public License (AGPL) version 3. * @@ -14,6 +13,12 @@ * */ +use serde::{Deserialize, Serialize}; + +use crate::config::SynapseConfig; +use crate::storage::store::{PerUserExperimentalFeature, Store}; + +/// `GET /_matrix/client/versions` response #[derive(Serialize, Deserialize, Clone, Debug)] struct VersionsResponse { versions: Vec, @@ -21,38 +26,45 @@ struct VersionsResponse { unstable_features: std::collections::BTreeMap, } +/// Assemble a `/versions` response async fn get_versions( + store: Store, user_id: Option<&str>, - config: + config: SynapseConfig, ) -> VersionsResponse { - match user_id { + let msc3881_enabled = match user_id { Some(user_id) => { - msc3881_enabled = store.is_feature_enabled( - user_id, ExperimentalFeature.MSC3881 - ).await; - msc3575_enabled = store.is_feature_enabled( - user_id, ExperimentalFeature.MSC3575 - ).await; - }, - None => { - msc3881_enabled = config.experimental.msc3881_enabled; - msc3575_enabled = config.experimental.msc3575_enabled; + store + .is_feature_enabled(user_id, PerUserExperimentalFeature::MSC3881) + .await } - } + None => config.experimental.msc3881_enabled, + }; + + let msc3575_enabled = match user_id { + Some(user_id) => { + store + .is_feature_enabled(user_id, PerUserExperimentalFeature::MSC3575) + .await + } + None => { + config.experimental.msc3575_enabled; + } + }; // TODO: Calculate these once since they shouldn't change after start-up. - e2ee_forced_public = ( - RoomCreationPreset.PUBLIC_CHAT - in config.room.encryption_enabled_by_default_for_room_presets - ); - e2ee_forced_private = ( - RoomCreationPreset.PRIVATE_CHAT - in config.room.encryption_enabled_by_default_for_room_presets - ); - e2ee_forced_trusted_private = ( - RoomCreationPreset.TRUSTED_PRIVATE_CHAT - in config.room.encryption_enabled_by_default_for_room_presets - ); + // e2ee_forced_public = ( + // RoomCreationPreset.PUBLIC_CHAT + // in config.room.encryption_enabled_by_default_for_room_presets + // ); + // e2ee_forced_private = ( + // RoomCreationPreset.PRIVATE_CHAT + // in config.room.encryption_enabled_by_default_for_room_presets + // ); + // e2ee_forced_trusted_private = ( + // RoomCreationPreset.TRUSTED_PRIVATE_CHAT + // in config.room.encryption_enabled_by_default_for_room_presets + // ); return VersionsResponse { versions: Vec::from([ @@ -63,100 +75,100 @@ async fn get_versions( // middle number is the major revision when at 0.X.Y (as opposed to // X.Y.Z). And we need to decide whether it's fair to make clients // parse the version string to figure out what's going on. - "r0.0.1", - "r0.1.0", - "r0.2.0", - "r0.3.0", - "r0.4.0", - "r0.5.0", - "r0.6.0", - "r0.6.1", - "v1.1", - "v1.2", - "v1.3", - "v1.4", - "v1.5", - "v1.6", - "v1.7", - "v1.8", - "v1.9", - "v1.10", - "v1.11", - "v1.12", + "r0.0.1".to_string(), + "r0.1.0".to_string(), + "r0.2.0".to_string(), + "r0.3.0".to_string(), + "r0.4.0".to_string(), + "r0.5.0".to_string(), + "r0.6.0".to_string(), + "r0.6.1".to_string(), + "v1.1".to_string(), + "v1.2".to_string(), + "v1.3".to_string(), + "v1.4".to_string(), + "v1.5".to_string(), + "v1.6".to_string(), + "v1.7".to_string(), + "v1.8".to_string(), + "v1.9".to_string(), + "v1.10".to_string(), + "v1.11".to_string(), + "v1.12".to_string(), ]), unstable_features: BTreeMap::from([ - // Implements support for label-based filtering as described in - // MSC2326. - ("org.matrix.label_based_filtering": true), - // Implements support for cross signing as described in MSC1756 - ("org.matrix.e2e_cross_signing": true), - // Implements additional endpoints as described in MSC2432 - ("org.matrix.msc2432": true), - // Implements additional endpoints as described in MSC2666 - ("uk.half-shot.msc2666.query_mutual_rooms.stable": true), - // Whether new rooms will be set to encrypted or not (based on presets). - ("io.element.e2ee_forced.public": e2ee_forced_public), - ("io.element.e2ee_forced.private": e2ee_forced_private), - ("io.element.e2ee_forced.trusted_private": e2ee_forced_trusted_private), - // Supports the busy presence state described in MSC3026. - ("org.matrix.msc3026.busy_presence": config.experimental.msc3026_enabled), - // Supports receiving private read receipts as per MSC2285 - ("org.matrix.msc2285.stable": true), // TODO: Remove when MSC2285 becomes a part of the spec - // Supports filtering of /publicRooms by room type as per MSC3827 - ("org.matrix.msc3827.stable": true), - // Adds support for thread relations, per MSC3440. - ("org.matrix.msc3440.stable": true), // TODO: remove when "v1.3" is added above - // Support for thread read receipts & notification counts. - ("org.matrix.msc3771": true), - ("org.matrix.msc3773": config.experimental.msc3773_enabled), - // Allows moderators to fetch redacted event content as described in MSC2815 - ("fi.mau.msc2815": config.experimental.msc2815_enabled), - // Adds a ping endpoint for appservices to check HS->AS connection - ("fi.mau.msc2659.stable": true), // TODO: remove when "v1.7" is added above - // TODO: this is no longer needed once unstable MSC3882 does not need to be supported: - ("org.matrix.msc3882": config.auth.login_via_existing_enabled), + // // Implements support for label-based filtering as described in + // // MSC2326. + // ("org.matrix.label_based_filtering", true), + // // Implements support for cross signing as described in MSC1756 + // ("org.matrix.e2e_cross_signing", true), + // // Implements additional endpoints as described in MSC2432 + // ("org.matrix.msc2432", true), + // // Implements additional endpoints as described in MSC2666 + // ("uk.half-shot.msc2666.query_mutual_rooms.stable", true), + // // Whether new rooms will be set to encrypted or not (based on presets). + // ("io.element.e2ee_forced.public", e2ee_forced_public), + // ("io.element.e2ee_forced.private", e2ee_forced_private), + // ("io.element.e2ee_forced.trusted_private", e2ee_forced_trusted_private), + // // Supports the busy presence state described in MSC3026. + // ("org.matrix.msc3026.busy_presence", config.experimental.msc3026_enabled), + // // Supports receiving private read receipts as per MSC2285 + // ("org.matrix.msc2285.stable", true), // TODO: Remove when MSC2285 becomes a part of the spec + // // Supports filtering of /publicRooms by room type as per MSC3827 + // ("org.matrix.msc3827.stable", true), + // // Adds support for thread relations, per MSC3440. + // ("org.matrix.msc3440.stable", true), // TODO: remove when "v1.3" is added above + // // Support for thread read receipts & notification counts. + // ("org.matrix.msc3771", true), + // ("org.matrix.msc3773", config.experimental.msc3773_enabled), + // // Allows moderators to fetch redacted event content as described in MSC2815 + // ("fi.mau.msc2815", config.experimental.msc2815_enabled), + // // Adds a ping endpoint for appservices to check HS->AS connection + // ("fi.mau.msc2659.stable", true), // TODO: remove when "v1.7" is added above + // // TODO: this is no longer needed once unstable MSC3882 does not need to be supported: + // ("org.matrix.msc3882", config.auth.login_via_existing_enabled), // Adds support for remotely enabling/disabling pushers, as per MSC3881 - ("org.matrix.msc3881": msc3881_enabled), - // Adds support for filtering /messages by event relation. - ("org.matrix.msc3874": config.experimental.msc3874_enabled), - // Adds support for relation-based redactions as per MSC3912. - ("org.matrix.msc3912": config.experimental.msc3912_enabled), - // Whether recursively provide relations is supported. - // TODO This is no longer needed once unstable MSC3981 does not need to be supported. - ("org.matrix.msc3981": true), - // Adds support for deleting account data. - ("org.matrix.msc3391": config.experimental.msc3391_enabled), - // Allows clients to inhibit profile update propagation. - ("org.matrix.msc4069": config.experimental.msc4069_profile_inhibit_propagation), - // Allows clients to handle push for encrypted events. - ("org.matrix.msc4028": config.experimental.msc4028_push_encrypted_events), - // MSC4108: Mechanism to allow OIDC sign in and E2EE set up via QR code - 2024 version - ("org.matrix.msc4108": ( - config.experimental.msc4108_enabled - or ( - config.experimental.msc4108_delegation_endpoint - is not None - ) - )), - // MSC4140: Delayed events - ("org.matrix.msc4140": bool(config.server.max_event_delay_ms)), + ("org.matrix.msc3881", msc3881_enabled), + // // Adds support for filtering /messages by event relation. + // ("org.matrix.msc3874", config.experimental.msc3874_enabled), + // // Adds support for relation-based redactions as per MSC3912. + // ("org.matrix.msc3912", config.experimental.msc3912_enabled), + // // Whether recursively provide relations is supported. + // // TODO This is no longer needed once unstable MSC3981 does not need to be supported. + // ("org.matrix.msc3981", true), + // // Adds support for deleting account data. + // ("org.matrix.msc3391", config.experimental.msc3391_enabled), + // // Allows clients to inhibit profile update propagation. + // ("org.matrix.msc4069", config.experimental.msc4069_profile_inhibit_propagation), + // // Allows clients to handle push for encrypted events. + // ("org.matrix.msc4028", config.experimental.msc4028_push_encrypted_events), + // // MSC4108: Mechanism to allow OIDC sign in and E2EE set up via QR code - 2024 version + // ("org.matrix.msc4108", ( + // config.experimental.msc4108_enabled + // or ( + // config.experimental.msc4108_delegation_endpoint + // is not None + // ) + // )), + // // MSC4140: Delayed events + // ("org.matrix.msc4140", bool(config.server.max_event_delay_ms)), // Simplified sliding sync - ("org.matrix.simplified_msc3575": msc3575_enabled), - // Arbitrary key-value profile fields. - ("uk.tcpip.msc4133": config.experimental.msc4133_enabled), - ("uk.tcpip.msc4133.stable": true), - // MSC4155: Invite filtering - ("org.matrix.msc4155": config.experimental.msc4155_enabled), - // MSC4306: Support for thread subscriptions - ("org.matrix.msc4306": config.experimental.msc4306_enabled), - // MSC4169: Backwards-compatible redaction sending using `/send` - ("com.beeper.msc4169": config.experimental.msc4169_enabled), - // MSC4354: Sticky events - ("org.matrix.msc4354": config.experimental.msc4354_enabled), - // MSC4380: Invite blocking - ("org.matrix.msc4380.stable": true), - // MSC4445: Sync timeline order - ("org.matrix.msc4445.initial_sync_timeline_topological_ordering": true), + ("org.matrix.simplified_msc3575", msc3575_enabled), + // // Arbitrary key-value profile fields. + // ("uk.tcpip.msc4133", config.experimental.msc4133_enabled), + // ("uk.tcpip.msc4133.stable", true), + // // MSC4155: Invite filtering + // ("org.matrix.msc4155", config.experimental.msc4155_enabled), + // // MSC4306: Support for thread subscriptions + // ("org.matrix.msc4306", config.experimental.msc4306_enabled), + // // MSC4169: Backwards-compatible redaction sending using `/send` + // ("com.beeper.msc4169", config.experimental.msc4169_enabled), + // // MSC4354: Sticky events + // ("org.matrix.msc4354", config.experimental.msc4354_enabled), + // // MSC4380: Invite blocking + // ("org.matrix.msc4380.stable", true), + // // MSC4445: Sync timeline order + // ("org.matrix.msc4445.initial_sync_timeline_topological_ordering", true), ]), - } + }; } diff --git a/rust/src/lib.rs b/rust/src/lib.rs index a5ce7b5a4e..38bae6e77a 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -6,10 +6,11 @@ use pyo3_log::ResetHandle; pub mod acl; pub mod canonical_json; -pub mod db; +pub mod config; pub mod duration; pub mod errors; pub mod events; +pub mod handlers; pub mod http; pub mod http_client; pub mod identifier; @@ -20,6 +21,7 @@ pub mod push; pub mod rendezvous; pub mod room_versions; pub mod segmenter; +pub mod storage; lazy_static! { static ref LOGGING_HANDLE: ResetHandle = pyo3_log::init(); @@ -67,6 +69,7 @@ fn synapse_rust(py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> { acl::register_module(py, m)?; push::register_module(py, m)?; events::register_module(py, m)?; + handlers::register_module(py, m)?; http_client::register_module(py, m)?; rendezvous::register_module(py, m)?; msc4388_rendezvous::register_module(py, m)?; diff --git a/rust/src/db/db.rs b/rust/src/storage/db/db.rs similarity index 100% rename from rust/src/db/db.rs rename to rust/src/storage/db/db.rs diff --git a/rust/src/db/mod.rs b/rust/src/storage/db/mod.rs similarity index 100% rename from rust/src/db/mod.rs rename to rust/src/storage/db/mod.rs diff --git a/rust/src/db/python_db_pool.rs b/rust/src/storage/db/python_db_pool.rs similarity index 100% rename from rust/src/db/python_db_pool.rs rename to rust/src/storage/db/python_db_pool.rs diff --git a/rust/src/storage/mod.rs b/rust/src/storage/mod.rs new file mode 100644 index 0000000000..735fcecb26 --- /dev/null +++ b/rust/src/storage/mod.rs @@ -0,0 +1,17 @@ +/* + * This file is licensed under the Affero General Public License (AGPL) version 3. + * + * Copyright (C) 2026 Element Creations Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * See the GNU Affero General Public License for more details: + * . + * + */ + +pub mod db; +pub mod store; diff --git a/rust/src/storage/store.rs b/rust/src/storage/store.rs new file mode 100644 index 0000000000..0f582d94f3 --- /dev/null +++ b/rust/src/storage/store.rs @@ -0,0 +1,29 @@ +/* + * This file is licensed under the Affero General Public License (AGPL) version 3. + * + * Copyright (C) 2026 Element Creations Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * See the GNU Affero General Public License for more details: + * . + * + */ + +/// Currently supported per-user features +pub enum PerUserExperimentalFeature { + MSC3881, + MSC3575, + MSC4222, +} + +pub struct Store {} + +impl Store { + pub fn is_feature_enabled(feature: PerUserExperimentalFeature) -> Result { + todo!("..."); + } +} diff --git a/synapse/storage/util/id_generators.py b/synapse/storage/util/id_generators.py index 1e053be6af..4534ce85e7 100644 --- a/synapse/storage/util/id_generators.py +++ b/synapse/storage/util/id_generators.py @@ -831,6 +831,8 @@ class MultiWriterIdGenerator(AbstractStreamIdGenerator): # Hacky debug logging to attempt to trace https://github.com/element-hq/synapse/issues/19795 if ( issue9533_logger.isEnabledFor(logging.DEBUG) + # Only log if we are the instance that is doing the persisting + and our_current_position > 0 and self._stream_name == "to_device" ): issue9533_logger.debug(