sdk: Replace Sled with SQLite as defaut store

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
This commit is contained in:
Kévin Commaille
2023-04-26 17:47:27 +02:00
committed by Jonas Platte
parent 09e446b1d5
commit ea826a257d
16 changed files with 82 additions and 51 deletions
+3 -3
View File
@@ -34,9 +34,9 @@ jobs:
matrix:
name:
- no-encryption
- no-sled
- no-encryption-and-sled
- sled-cryptostore
- no-sqlite
- no-encryption-and-sqlite
- sqlite-cryptostore
- rustls-tls
- markdown
- socks
Generated
+1 -1
View File
@@ -2633,7 +2633,7 @@ dependencies = [
"matrix-sdk-base",
"matrix-sdk-common",
"matrix-sdk-indexeddb",
"matrix-sdk-sled",
"matrix-sdk-sqlite",
"matrix-sdk-test",
"mime",
"mime2ext",
+1 -1
View File
@@ -19,7 +19,7 @@ e2e-encryption = [
"matrix-sdk/e2e-encryption"
]
eyre = ["matrix-sdk/eyre"]
sled = ["matrix-sdk/sled"]
sqlite = ["matrix-sdk/sqlite"]
markdown = ["matrix-sdk/markdown"]
native-tls = ["matrix-sdk/native-tls"]
+1 -1
View File
@@ -17,7 +17,7 @@
//! The storage layer for the [`OlmMachine`] can be customized using a trait.
//! Implementing your own [`CryptoStore`]
//!
//! An in-memory only store is provided as well as a Sled based one, depending
//! An in-memory only store is provided as well as a SQLite-based one, depending
//! on your needs and targets a custom store may be implemented, e.g. for
//! `wasm-unknown-unknown` an indexeddb store would be needed
//!
+26
View File
@@ -16,7 +16,10 @@
allow(dead_code, unused_imports)
)]
use std::path::Path;
use deadpool_sqlite::Object as SqliteConn;
use matrix_sdk_base::store::StoreConfig;
use matrix_sdk_store_encryption::StoreCipher;
#[cfg(feature = "crypto-store")]
@@ -63,3 +66,26 @@ fn init_logging() {
.with(tracing_subscriber::fmt::layer().with_test_writer())
.init();
}
/// Create a [`StoreConfig`] with an opened [`SqliteStateStore`] in the given
/// directory and using the given passphrase. If the `crypto-store` feature is
/// enabled, a [`SqliteCryptoStore`] with the same parameters is also opened.
#[cfg(feature = "state-store")]
pub async fn make_store_config(
path: &Path,
passphrase: Option<&str>,
) -> Result<StoreConfig, OpenStoreError> {
let state_store = SqliteStateStore::open(path, passphrase).await?;
let config = StoreConfig::new().state_store(state_store);
#[cfg(feature = "crypto-store")]
{
let crypto_store = SqliteCryptoStore::open(path, passphrase).await?;
Ok(config.crypto_store(crypto_store))
}
#[cfg(not(feature = "crypto-store"))]
{
Ok(config)
}
}
+2
View File
@@ -3,6 +3,8 @@
- `Common::members` and `Common::members_no_sync` take a `RoomMemberships` to be able to filter the
results by any membership state.
- `Common::active_members(_no_sync)` and `Common::joined_members(_no_sync)` are deprecated.
- `matrix-sdk-sqlite` is the new default store implementation outside of WASM, behind the `sqlite` feature.
- The `sled` feature was removed. It is still possible to use `matrix-sdk-sled` as a custom store.
# 0.6.2
+5 -5
View File
@@ -19,7 +19,7 @@ rustdoc-args = ["--cfg", "docsrs"]
default = [
"e2e-encryption",
"automatic-room-key-forwarding",
"sled",
"sqlite",
"native-tls",
]
testing = []
@@ -27,12 +27,12 @@ testing = []
e2e-encryption = [
"matrix-sdk-base/e2e-encryption",
"matrix-sdk-base/automatic-room-key-forwarding",
"matrix-sdk-sled?/crypto-store", # activate crypto-store on sled if given
"matrix-sdk-sqlite?/crypto-store", # activate crypto-store on sqlite if given
"matrix-sdk-indexeddb?/e2e-encryption", # activate on indexeddb if given
]
js = ["matrix-sdk-common/js", "matrix-sdk-base/js"]
sled = ["dep:matrix-sdk-sled", "matrix-sdk-sled?/state-store"]
sqlite = ["dep:matrix-sdk-sqlite", "matrix-sdk-sqlite?/state-store"]
indexeddb = ["dep:matrix-sdk-indexeddb"]
qrcode = ["e2e-encryption", "matrix-sdk-base/qrcode"]
@@ -57,7 +57,7 @@ experimental-sliding-sync = [
docsrs = [
"e2e-encryption",
"sled",
"sqlite",
"sso-login",
"qrcode",
"image-proc",
@@ -85,7 +85,7 @@ hyper = { version = "0.14.20", features = ["http1", "http2", "server"], optional
matrix-sdk-base = { version = "0.6.0", path = "../matrix-sdk-base", default_features = false }
matrix-sdk-common = { version = "0.6.0", path = "../matrix-sdk-common" }
matrix-sdk-indexeddb = { version = "0.2.0", path = "../matrix-sdk-indexeddb", default-features = false, optional = true }
matrix-sdk-sled = { version = "0.2.0", path = "../matrix-sdk-sled", default-features = false, optional = true }
matrix-sdk-sqlite = { version = "0.1.0", path = "../matrix-sdk-sqlite", default-features = false, optional = true }
mime = "0.3.16"
mime2ext = "0.1.52"
once_cell = { workspace = true }
+1 -1
View File
@@ -65,7 +65,7 @@ The following crate feature flags are available:
| `js` | No | Enables JavaScript API usage for things like the current system time on WASM (does nothing on other targets) |
| `markdown` | No | Support for sending Markdown-formatted messages |
| `qrcode` | Yes | QR code verification support |
| `sled` | Yes | Persistent storage of state and E2EE data (optionally, if feature `e2e-encryption` is enabled), via Sled |
| `sqlite` | Yes | Persistent storage of state and E2EE data (optionally, if feature `e2e-encryption` is enabled), via SQLite |
| `indexeddb` | No | Persistent storage of state and E2EE data (optionally, if feature `e2e-encryption` is enabled) for browsers, via IndexedDB |
| `socks` | No | SOCKS support in the default HTTP client, [`reqwest`] |
| `sso-login` | No | Support for SSO login with a local HTTP server |
+16 -16
View File
@@ -118,19 +118,19 @@ impl ClientBuilder {
self
}
/// Set up the store configuration for a sled store.
/// Set up the store configuration for a SQLite store.
///
/// This is the same as
/// <code>.[store_config](Self::store_config)([matrix_sdk_sled]::[make_store_config](matrix_sdk_sled::make_store_config)(path, passphrase)?)</code>.
/// <code>.[store_config](Self::store_config)([matrix_sdk_sqlite]::[make_store_config](matrix_sdk_sqlite::make_store_config)(path, passphrase)?)</code>.
/// except it delegates the actual store config creation to when
/// `.build().await` is called.
#[cfg(feature = "sled")]
pub fn sled_store(
#[cfg(feature = "sqlite")]
pub fn sqlite_store(
mut self,
path: impl AsRef<std::path::Path>,
passphrase: Option<&str>,
) -> Self {
self.store_config = BuilderStoreConfig::Sled {
self.store_config = BuilderStoreConfig::Sqlite {
path: path.as_ref().to_owned(),
passphrase: passphrase.map(ToOwned::to_owned),
};
@@ -342,9 +342,9 @@ impl ClientBuilder {
#[allow(clippy::infallible_destructuring_match)]
let store_config = match self.store_config {
#[cfg(feature = "sled")]
BuilderStoreConfig::Sled { path, passphrase } => {
matrix_sdk_sled::make_store_config(&path, passphrase.as_deref()).await?
#[cfg(feature = "sqlite")]
BuilderStoreConfig::Sqlite { path, passphrase } => {
matrix_sdk_sqlite::make_store_config(&path, passphrase.as_deref()).await?
}
#[cfg(feature = "indexeddb")]
BuilderStoreConfig::IndexedDb { name, passphrase } => {
@@ -480,8 +480,8 @@ impl Default for HttpConfig {
#[derive(Clone)]
enum BuilderStoreConfig {
#[cfg(feature = "sled")]
Sled {
#[cfg(feature = "sqlite")]
Sqlite {
path: std::path::PathBuf,
passphrase: Option<String>,
},
@@ -498,9 +498,9 @@ impl fmt::Debug for BuilderStoreConfig {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
#[allow(clippy::infallible_destructuring_match)]
match self {
#[cfg(feature = "sled")]
Self::Sled { path, .. } => {
f.debug_struct("Sled").field("path", path).finish_non_exhaustive()
#[cfg(feature = "sqlite")]
Self::Sqlite { path, .. } => {
f.debug_struct("Sqlite").field("path", path).finish_non_exhaustive()
}
#[cfg(feature = "indexeddb")]
Self::IndexedDb { name, .. } => {
@@ -535,10 +535,10 @@ pub enum ClientBuildError {
#[error(transparent)]
IndexeddbStore(#[from] matrix_sdk_indexeddb::OpenStoreError),
/// Error opening the sled store.
#[cfg(feature = "sled")]
/// Error opening the sqlite store.
#[cfg(feature = "sqlite")]
#[error(transparent)]
SledStore(#[from] matrix_sdk_sled::OpenStoreError),
SqliteStore(#[from] matrix_sdk_sqlite::OpenStoreError),
}
impl ClientBuildError {
+1 -1
View File
@@ -216,7 +216,7 @@ is **not** supported using the default store.
| Failure | Cause | Fix |
| ------------------- | ----- | ----------- |
| No messages get encrypted nor decrypted | The `e2e-encryption` feature is disabled | [Enable the feature in your `Cargo.toml` file] |
| Messages that were decryptable aren't after a restart | Storage isn't setup to be persistent | Ensure you've activated the persistent storage backend feature, e.g. `sled` |
| Messages that were decryptable aren't after a restart | Storage isn't setup to be persistent | Ensure you've activated the persistent storage backend feature, e.g. `sqlite` |
| Messages are encrypted but can't be decrypted | The access token that the client is using is tied to another device | Clear storage to create a new device, read the [Restoring a Client] section |
| Messages don't get encrypted but get decrypted | The `m.room.encryption` event is missing | Make sure encryption is [enabled] for the room and the event isn't [filtered] out, otherwise it might be a deserialization bug |
+5 -5
View File
@@ -92,7 +92,7 @@ async fn restore_session(session_file: &Path) -> anyhow::Result<(Client, Option<
// Build the client with the previous settings from the session.
let client = Client::builder()
.homeserver_url(client_session.homeserver)
.sled_store(client_session.db_path, Some(&client_session.passphrase))
.sqlite_store(client_session.db_path, Some(&client_session.passphrase))
.build()
.await?;
@@ -165,7 +165,7 @@ async fn build_client(data_dir: &Path) -> anyhow::Result<(Client, ClientSession)
// Generating a subfolder for the database is not mandatory, but it is useful if
// you allow several clients to run at the same time. Each one must have a
// separate database, which is a different folder with the sled store.
// separate database, which is a different folder with the SQLite store.
let db_subfolder: String =
(&mut rng).sample_iter(Alphanumeric).take(7).map(char::from).collect();
let db_path = data_dir.join(db_subfolder);
@@ -186,10 +186,10 @@ async fn build_client(data_dir: &Path) -> anyhow::Result<(Client, ClientSession)
match Client::builder()
.homeserver_url(&homeserver)
// We use the sled store, which is enabled by default. This is the crucial part to
// We use the SQLite store, which is enabled by default. This is the crucial part to
// persist the encryption setup.
// Note that other store backends are available and you an even implement your own.
.sled_store(&db_path, Some(&passphrase))
// Note that other store backends are available and you can even implement your own.
.sqlite_store(&db_path, Some(&passphrase))
.build()
.await
{
+1 -1
View File
@@ -18,5 +18,5 @@ url = "2.2.2"
[dependencies.matrix-sdk]
path = "../../crates/matrix-sdk"
features = ["experimental-timeline", "sled"]
features = ["experimental-timeline"]
version = "0.6.0"
@@ -36,7 +36,7 @@ pub fn test_server_conf() -> (String, String) {
)
}
pub async fn get_client_for_user(username: String, use_sled_store: bool) -> Result<Client> {
pub async fn get_client_for_user(username: String, use_sqlite_store: bool) -> Result<Client> {
let mut users = USERS.lock().await;
if let Some((client, _)) = users.get(&username) {
return Ok(client.clone());
@@ -50,8 +50,8 @@ pub async fn get_client_for_user(username: String, use_sled_store: bool) -> Resu
.user_agent("matrix-sdk-integation-tests")
.homeserver_url(homeserver_url)
.request_config(RequestConfig::short_retry());
let client = if use_sled_store {
client_builder.sled_store(tmp_dir.path(), None).build().await?
let client = if use_sqlite_store {
client_builder.sqlite_store(tmp_dir.path(), None).build().await?
} else {
client_builder.build().await?
};
@@ -18,7 +18,7 @@ use crate::helpers::get_client_for_user;
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn test_repeated_join_leave() -> Result<()> {
let peter = get_client_for_user("peter".to_owned(), true).await?;
// FIXME: Run once with memory, once with sled
// FIXME: Run once with memory, once with SQLite
let karl = get_client_for_user("karl".to_owned(), false).await?;
let karl_id = karl.user_id().expect("karl has a userid!").to_owned();
@@ -27,10 +27,13 @@ use matrix_sdk::{
};
use matrix_sdk_integration_testing::helpers::get_client_for_user;
async fn setup(name: String, use_sled_store: bool) -> anyhow::Result<(Client, SlidingSyncBuilder)> {
async fn setup(
name: String,
use_sqlite_store: bool,
) -> anyhow::Result<(Client, SlidingSyncBuilder)> {
let sliding_sync_proxy_url =
option_env!("SLIDING_SYNC_PROXY_URL").unwrap_or("http://localhost:8338").to_owned();
let client = get_client_for_user(name, use_sled_store).await?;
let client = get_client_for_user(name, use_sqlite_store).await?;
let sliding_sync_builder = client
.sliding_sync()
.await
@@ -47,10 +50,10 @@ async fn random_setup_with_rooms(
async fn random_setup_with_rooms_opt_store(
number_of_rooms: usize,
use_sled_store: bool,
use_sqlite_store: bool,
) -> anyhow::Result<(Client, SlidingSyncBuilder)> {
let namespace = uuid::Uuid::new_v4().to_string();
let (client, sliding_sync_builder) = setup(namespace.clone(), use_sled_store).await?;
let (client, sliding_sync_builder) = setup(namespace.clone(), use_sqlite_store).await?;
for room_num in 0..number_of_rooms {
make_room(&client, format!("{namespace}-{room_num}")).await?
+8 -8
View File
@@ -63,9 +63,9 @@ enum CiCommand {
#[derive(Subcommand, PartialEq, Eq, PartialOrd, Ord)]
enum FeatureSet {
NoEncryption,
NoSled,
NoEncryptionAndSled,
SledCryptostore,
NoSqlite,
NoEncryptionAndSqlite,
SqliteCryptostore,
RustlsTls,
Markdown,
Socks,
@@ -194,13 +194,13 @@ fn run_feature_tests(cmd: Option<FeatureSet>) -> Result<()> {
let args = BTreeMap::from([
(
FeatureSet::NoEncryption,
"--no-default-features --features sled,native-tls,experimental-sliding-sync",
"--no-default-features --features sqlite,native-tls,experimental-sliding-sync",
),
(FeatureSet::NoSled, "--no-default-features --features e2e-encryption,native-tls"),
(FeatureSet::NoEncryptionAndSled, "--no-default-features --features native-tls"),
(FeatureSet::NoSqlite, "--no-default-features --features e2e-encryption,native-tls"),
(FeatureSet::NoEncryptionAndSqlite, "--no-default-features --features native-tls"),
(
FeatureSet::SledCryptostore,
"--no-default-features --features e2e-encryption,sled,native-tls",
FeatureSet::SqliteCryptostore,
"--no-default-features --features e2e-encryption,sqlite,native-tls",
),
(FeatureSet::RustlsTls, "--no-default-features --features rustls-tls"),
(FeatureSet::Markdown, "--features markdown"),