diff --git a/mls-rs-uniffi/Cargo.toml b/mls-rs-uniffi/Cargo.toml index 62ab5fc3..7e7a0c9b 100644 --- a/mls-rs-uniffi/Cargo.toml +++ b/mls-rs-uniffi/Cargo.toml @@ -21,10 +21,10 @@ mls-rs = { version = "0.39.0", path = "../mls-rs" } mls-rs-core = { version = "0.18.0", path = "../mls-rs-core" } mls-rs-crypto-openssl = { version = "0.9.0", path = "../mls-rs-crypto-openssl" } thiserror = "1.0.57" -uniffi = "0.26.0" +uniffi = { git = "https://github.com/mozilla/uniffi-rs/", rev = "6b09f11", version = "0.26.0" } [target.'cfg(mls_build_async)'.dependencies] tokio = { version = "1.36.0", features = ["sync"] } [dev-dependencies] -uniffi_bindgen = "0.26.0" +uniffi_bindgen = { git = "https://github.com/mozilla/uniffi-rs/", rev = "6b09f11", version = "0.26.0" } diff --git a/mls-rs-uniffi/src/config.rs b/mls-rs-uniffi/src/config.rs index a7716672..4bf2e6b0 100644 --- a/mls-rs-uniffi/src/config.rs +++ b/mls-rs-uniffi/src/config.rs @@ -28,11 +28,11 @@ impl mls_rs_core::group::GroupStateStorage for ClientGroupStorage { type Error = Error; async fn state(&self, group_id: &[u8]) -> Result>, Self::Error> { - self.0.state(group_id.to_vec()) + self.0.state(group_id.to_vec()).await } async fn epoch(&self, group_id: &[u8], epoch_id: u64) -> Result>, Self::Error> { - self.0.epoch(group_id.to_vec(), epoch_id) + self.0.epoch(group_id.to_vec(), epoch_id).await } async fn write( @@ -41,16 +41,18 @@ impl mls_rs_core::group::GroupStateStorage for ClientGroupStorage { inserts: Vec, updates: Vec, ) -> Result<(), Self::Error> { - self.0.write( - state.id, - state.data, - inserts.into_iter().map(Into::into).collect(), - updates.into_iter().map(Into::into).collect(), - ) + self.0 + .write( + state.id, + state.data, + inserts.into_iter().map(Into::into).collect(), + updates.into_iter().map(Into::into).collect(), + ) + .await } async fn max_epoch_id(&self, group_id: &[u8]) -> Result, Self::Error> { - self.0.max_epoch_id(group_id.to_vec()) + self.0.max_epoch_id(group_id.to_vec()).await } } diff --git a/mls-rs-uniffi/src/config/group_state.rs b/mls-rs-uniffi/src/config/group_state.rs index e4fc54a0..5ff0c632 100644 --- a/mls-rs-uniffi/src/config/group_state.rs +++ b/mls-rs-uniffi/src/config/group_state.rs @@ -1,6 +1,9 @@ use mls_rs::error::IntoAnyError; use std::fmt::Debug; +#[cfg(not(mls_build_async))] use std::sync::Mutex; +#[cfg(mls_build_async)] +use tokio::sync::Mutex; use crate::Error; @@ -28,9 +31,9 @@ impl From for mls_rs_core::group::EpochRecord { } } +#[uniffi::export(with_foreign)] #[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)] #[cfg_attr(mls_build_async, maybe_async::must_be_async)] -#[uniffi::export(with_foreign)] pub trait GroupStateStorage: Send + Sync + Debug { async fn state(&self, group_id: Vec) -> Result>, Error>; async fn epoch(&self, group_id: Vec, epoch_id: u64) -> Result>, Error>; @@ -59,9 +62,15 @@ impl GroupStateStorageAdapter { Self(Mutex::new(group_state_storage)) } + #[cfg(not(mls_build_async))] fn inner(&self) -> std::sync::MutexGuard<'_, S> { self.0.lock().unwrap() } + + #[cfg(mls_build_async)] + async fn inner(&self) -> tokio::sync::MutexGuard<'_, S> { + self.0.lock().await + } } #[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)] @@ -73,13 +82,17 @@ where { async fn state(&self, group_id: Vec) -> Result>, Error> { self.inner() + .await .state(&group_id) + .await .map_err(|err| err.into_any_error().into()) } async fn epoch(&self, group_id: Vec, epoch_id: u64) -> Result>, Error> { self.inner() + .await .epoch(&group_id, epoch_id) + .await .map_err(|err| err.into_any_error().into()) } @@ -91,17 +104,21 @@ where epoch_updates: Vec, ) -> Result<(), Error> { self.inner() + .await .write( mls_rs_core::group::GroupState { id, data }, epoch_inserts.into_iter().map(Into::into).collect(), epoch_updates.into_iter().map(Into::into).collect(), ) + .await .map_err(|err| err.into_any_error().into()) } async fn max_epoch_id(&self, group_id: Vec) -> Result, Error> { self.inner() + .await .max_epoch_id(&group_id) + .await .map_err(|err| err.into_any_error().into()) } } diff --git a/mls-rs-uniffi/src/lib.rs b/mls-rs-uniffi/src/lib.rs index a7a027a1..191c302e 100644 --- a/mls-rs-uniffi/src/lib.rs +++ b/mls-rs-uniffi/src/lib.rs @@ -262,6 +262,7 @@ impl TryFrom for CipherSuite { /// See [`mls_rs::CipherSuiteProvider::signature_key_generate`] /// for details. #[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)] +#[cfg_attr(mls_build_async, maybe_async::must_be_async)] #[uniffi::export] pub async fn generate_signature_keypair( cipher_suite: CipherSuite, @@ -292,6 +293,7 @@ pub struct Client { } #[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)] +#[cfg_attr(mls_build_async, maybe_async::must_be_async)] #[uniffi::export] impl Client { /// Create a new client. @@ -495,6 +497,7 @@ pub struct Group { } #[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)] +#[cfg_attr(mls_build_async, maybe_async::must_be_async)] impl Group { #[cfg(not(mls_build_async))] fn inner(&self) -> std::sync::MutexGuard<'_, mls_rs::Group> { @@ -520,6 +523,7 @@ fn index_to_identity( /// Extract the basic credential identifier from a from a key package. #[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)] +#[cfg_attr(mls_build_async, maybe_async::must_be_async)] async fn signing_identity_to_identifier( signing_identity: &identity::SigningIdentity, ) -> Result, Error> { @@ -531,6 +535,7 @@ async fn signing_identity_to_identifier( } #[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)] +#[cfg_attr(mls_build_async, maybe_async::must_be_async)] #[uniffi::export] impl Group { /// Write the current state of the group to storage defined by @@ -545,8 +550,9 @@ impl Group { /// This function is used to provide the current group tree to new /// members when `use_ratchet_tree_extension` is set to false in /// `ClientConfig`. - pub fn export_tree(&self) -> Result { - self.inner().export_tree().try_into() + pub async fn export_tree(&self) -> Result { + let group = self.inner().await; + group.export_tree().try_into() } /// Perform a commit of received proposals (or an empty commit). diff --git a/mls-rs-uniffi/tests/custom_storage_sync.py b/mls-rs-uniffi/tests/custom_storage_sync.py index a8bec343..f192a992 100644 --- a/mls-rs-uniffi/tests/custom_storage_sync.py +++ b/mls-rs-uniffi/tests/custom_storage_sync.py @@ -62,7 +62,7 @@ def max_epoch_id(self, group_id: bytes): group_state_storage = PythonGroupStateStorage() -client_config = ClientConfig(group_state_storage, +client_config = ClientConfig(group_state_storage=group_state_storage, use_ratchet_tree_extension=True) key = generate_signature_keypair(CipherSuite.CURVE25519_AES128) diff --git a/mls-rs-uniffi/tests/scenarios.rs b/mls-rs-uniffi/tests/scenarios.rs index 6cceafad..a7989483 100644 --- a/mls-rs-uniffi/tests/scenarios.rs +++ b/mls-rs-uniffi/tests/scenarios.rs @@ -45,9 +45,5 @@ macro_rules! generate_python_tests { generate_python_tests!(generate_signature_keypair, None); generate_python_tests!(client_config_default_sync, None); generate_python_tests!(custom_storage_sync, None); - -// TODO(mulmarta): it'll break if we use async trait which will be -// supported in the next UniFFI release -// TODO(mgeisler): add back simple_scenario_async generate_python_tests!(simple_scenario_sync, None); generate_python_tests!(ratchet_tree_sync, None); diff --git a/mls-rs-uniffi/uniffi-bindgen/Cargo.toml b/mls-rs-uniffi/uniffi-bindgen/Cargo.toml index aa7a923c..a82c083b 100644 --- a/mls-rs-uniffi/uniffi-bindgen/Cargo.toml +++ b/mls-rs-uniffi/uniffi-bindgen/Cargo.toml @@ -7,4 +7,4 @@ publish = false # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -uniffi = { version = "0.26.0", features = ["cli"] } +uniffi = { git = "https://github.com/mozilla/uniffi-rs/", rev = "6b09f11", version = "0.26.0", features = ["cli"] }