From 51dcdac46d40eb04908fc993d52e28e012f751d0 Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Mon, 28 Aug 2023 15:48:19 +0200 Subject: [PATCH] TERRIBLE HACK: save the `pos` value in the crypto store --- crates/matrix-sdk/src/sliding_sync/cache.rs | 59 ++++++++++++++++----- crates/matrix-sdk/src/sliding_sync/mod.rs | 16 +++--- 2 files changed, 55 insertions(+), 20 deletions(-) diff --git a/crates/matrix-sdk/src/sliding_sync/cache.rs b/crates/matrix-sdk/src/sliding_sync/cache.rs index d3fb0928b..e3072e92e 100644 --- a/crates/matrix-sdk/src/sliding_sync/cache.rs +++ b/crates/matrix-sdk/src/sliding_sync/cache.rs @@ -15,7 +15,10 @@ use super::{ FrozenSlidingSync, FrozenSlidingSyncList, SlidingSync, SlidingSyncList, SlidingSyncPositionMarkers, }; -use crate::{sliding_sync::SlidingSyncListCachePolicy, Client, Result}; +use crate::{ + sliding_sync::{FrozenSlidingSyncPos, SlidingSyncListCachePolicy}, + Client, Result, +}; /// Be careful: as this is used as a storage key; changing it requires migrating /// data! @@ -57,9 +60,17 @@ async fn clean_storage( for list_name in lists.keys() { invalidate_cached_list(storage, storage_key, list_name).await; } - let _ = storage - .remove_custom_value(format_storage_key_for_sliding_sync(storage_key).as_bytes()) - .await; + let instance_storage_key = format_storage_key_for_sliding_sync(storage_key); + let _ = storage.remove_custom_value(instance_storage_key.as_bytes()).await; + + #[cfg(feature = "e2e-encryption")] + if let Some(olm_machine) = &*client.olm_machine().await { + // Invalidate the value stored for the TERRIBLE HACK. + let _ = olm_machine + .store() + .set_custom_value(&instance_storage_key, "".as_bytes().to_vec()) + .await; + } } /// Store the `SlidingSync`'s state in the storage. @@ -82,6 +93,18 @@ pub(super) async fn store_sliding_sync_state( ) .await?; + #[cfg(feature = "e2e-encryption")] + { + // FIXME (TERRIBLE HACK): we want to save `pos` in a cross-process safe manner, + // with both processes sharing the same database backend; that needs to + // go in the crypto process store at the moment, but should be fixed + // later on. + if let Some(olm_machine) = &*sliding_sync.inner.client.olm_machine().await { + let pos_blob = serde_json::to_vec(&FrozenSlidingSyncPos { pos: position.pos.clone() })?; + olm_machine.store().set_custom_value(&instance_storage_key, pos_blob).await?; + } + } + // Write every `SlidingSyncList` that's configured for caching into the store. let frozen_lists = { let rooms_lock = sliding_sync.inner.rooms.read().await; @@ -190,19 +213,16 @@ pub(super) async fn restore_sliding_sync_state( } let storage = client.store(); + let instance_storage_key = format_storage_key_for_sliding_sync(storage_key); // Preload the `SlidingSync` object from the cache. match storage - .get_custom_value(format_storage_key_for_sliding_sync(storage_key).as_bytes()) + .get_custom_value(instance_storage_key.as_bytes()) .await? .map(|custom_value| serde_json::from_slice::(&custom_value)) { // `SlidingSync` has been found and successfully deserialized. - Some(Ok(FrozenSlidingSync { - to_device_since, - delta_token: frozen_delta_token, - pos: frozen_pos, - })) => { + Some(Ok(FrozenSlidingSync { to_device_since, delta_token: frozen_delta_token })) => { trace!("Successfully read the `SlidingSync` from the cache"); // Only update the to-device token if we failed to read it from the crypto store // above. @@ -211,7 +231,22 @@ pub(super) async fn restore_sliding_sync_state( } restored_fields.delta_token = frozen_delta_token; - restored_fields.pos = frozen_pos; + + #[cfg(feature = "e2e-encryption")] + { + if let Some(olm_machine) = &*client.olm_machine().await { + if let Ok(Some(blob)) = + olm_machine.store().get_custom_value(&instance_storage_key).await + { + if let Ok(frozen_pos) = + serde_json::from_slice::(&blob) + { + trace!("Successfully read the `Sliding Sync` pos from the crypto store cache"); + restored_fields.pos = frozen_pos.pos; + } + } + } + } } // `SlidingSync` has been found, but it wasn't possible to deserialize it. It's @@ -445,7 +480,6 @@ mod tests { Some(bytes) => { let deserialized: FrozenSlidingSync = serde_json::from_slice(&bytes)?; assert_eq!(deserialized.delta_token, Some(delta_token.clone())); - assert_eq!(deserialized.pos, Some(pos.clone())); assert!(deserialized.to_device_since.is_none()); } ); @@ -481,7 +515,6 @@ mod tests { serde_json::to_vec(&FrozenSlidingSync { to_device_since: Some(to_device_token.clone()), delta_token: Some(delta_token.clone()), - pos: Some(pos.clone()), })?, ) .await?; diff --git a/crates/matrix-sdk/src/sliding_sync/mod.rs b/crates/matrix-sdk/src/sliding_sync/mod.rs index dcf749117..cf69fb0cb 100644 --- a/crates/matrix-sdk/src/sliding_sync/mod.rs +++ b/crates/matrix-sdk/src/sliding_sync/mod.rs @@ -877,21 +877,21 @@ struct FrozenSlidingSync { to_device_since: Option, #[serde(skip_serializing_if = "Option::is_none")] delta_token: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pos: Option, } impl FrozenSlidingSync { async fn new(position: &SlidingSyncPositionMarkers) -> Self { // The to-device token must be saved in the `FrozenCryptoSlidingSync` now. - Self { - delta_token: position.delta_token.clone(), - to_device_since: None, - pos: position.pos.clone(), - } + Self { delta_token: position.delta_token.clone(), to_device_since: None } } } +#[derive(Serialize, Deserialize)] +struct FrozenSlidingSyncPos { + #[serde(skip_serializing_if = "Option::is_none")] + pos: Option, +} + /// A summary of the updates received after a sync (like in /// [`SlidingSync::sync`]). #[derive(Debug, Clone)] @@ -1613,6 +1613,7 @@ mod tests { Ok(()) } + #[cfg(feature = "e2e-encryption")] #[async_test] async fn test_sliding_sync_doesnt_remember_pos() -> Result<()> { let server = MockServer::start().await; @@ -1707,6 +1708,7 @@ mod tests { Ok(()) } + #[cfg(feature = "e2e-encryption")] #[async_test] async fn test_sliding_sync_does_remember_pos() -> Result<()> { let server = MockServer::start().await;