diff --git a/native/native_rust_library/Cargo.lock b/native/native_rust_library/Cargo.lock --- a/native/native_rust_library/Cargo.lock +++ b/native/native_rust_library/Cargo.lock @@ -1248,6 +1248,7 @@ "argon2", "backup_client", "base64", + "comm-lib", "comm-opaque2", "cxx", "cxx-build", diff --git a/native/native_rust_library/Cargo.toml b/native/native_rust_library/Cargo.toml --- a/native/native_rust_library/Cargo.toml +++ b/native/native_rust_library/Cargo.toml @@ -5,6 +5,7 @@ license = "BSD-3-Clause" [dependencies] +comm-lib = { path = "../../shared/comm-lib" } cxx = "1.0" tokio = { version = "1.24", features = ["macros", "rt-multi-thread"] } tokio-util = "0.7.15" diff --git a/native/native_rust_library/src/backup.rs b/native/native_rust_library/src/backup.rs --- a/native/native_rust_library/src/backup.rs +++ b/native/native_rust_library/src/backup.rs @@ -198,39 +198,19 @@ promise_id: u32, ) { RUNTIME.spawn(async move { - let result = download_backup_data(backup_id.clone()) - .await - .map_err(|err| err.to_string()); - - let result = match result { - Ok(result) => result, - Err(error) => { - void_callback(error, promise_id); - return; - } - }; - - let (future_id, future) = future_manager::new_future::<()>().await; - restore_from_main_compaction( - &result.backup_restoration_path.to_string_lossy(), - &backup_data_key, - &max_version, - future_id, - ); - - if let Err(error) = future.await { - void_callback(error, promise_id); - return; - } - - if let Err(error) = - download_and_apply_logs(&backup_id, backup_log_data_key).await + let err_string = match restore_backup_data_helper( + backup_id, + backup_data_key, + backup_log_data_key, + max_version, + ) + .await { - void_callback(error.to_string(), promise_id); - return; - } + Ok(()) => "".to_string(), + Err(error) => error.to_string(), + }; - void_callback(String::new(), promise_id); + void_callback(err_string, promise_id); }); } @@ -448,7 +428,8 @@ async fn download_backup_data( backup_id: String, -) -> Result> { + backup_restoration_path: &PathBuf, +) -> Result<(), Box> { let backup_client = BackupClient::new(BACKUP_SOCKET_ADDR)?; let user_identity = get_user_identity_from_secure_store()?; @@ -461,14 +442,9 @@ .download_backup_data(&backup_data_descriptor, RequestedData::UserData) .await?; - let backup_restoration_path = - PathBuf::from(get_backup_directory_path()?).join("restore_compaction"); - - tokio::fs::write(&backup_restoration_path, encrypted_user_data).await?; + tokio::fs::write(backup_restoration_path, encrypted_user_data).await?; - Ok(CompactionDownloadResult { - backup_restoration_path, - }) + Ok(()) } async fn download_and_apply_logs( @@ -495,6 +471,34 @@ Ok(()) } +async fn restore_backup_data_helper( + backup_id: String, + backup_data_key: String, + backup_log_data_key: String, + max_version: String, +) -> Result<(), Box> { + let backup_restoration_path = + PathBuf::from(get_backup_directory_path()?).join("restore_compaction"); + + download_backup_data(backup_id.clone(), &backup_restoration_path).await?; + + // downloaded compaction will be removed when this gets out of scope + let _cleanup = comm_lib::tools::Defer::new(|| { + crate::utils::schedule_remove_file(&backup_restoration_path) + }); + + async_cpp_call!(restore_from_main_compaction( + &backup_restoration_path.to_string_lossy(), + &backup_data_key, + &max_version + )) + .await?; + + download_and_apply_logs(&backup_id, backup_log_data_key).await?; + + Ok(()) +} + fn get_user_identity_from_secure_store() -> Result { Ok(UserIdentity { @@ -535,10 +539,6 @@ pub version_info: BackupVersionInfo, } -struct CompactionDownloadResult { - backup_restoration_path: PathBuf, -} - /// Stores the Olm account in `pickled_account`. However, Olm account /// information might be out of date. We have decided we don't need /// to update this when one-time keys (OTKs) or prekeys change. diff --git a/native/native_rust_library/src/utils.rs b/native/native_rust_library/src/utils.rs --- a/native/native_rust_library/src/utils.rs +++ b/native/native_rust_library/src/utils.rs @@ -1,2 +1,13 @@ +use std::path::{Path, PathBuf}; + pub mod future_manager; pub mod jsi_callbacks; + +pub fn schedule_remove_file(path: &Path) { + let path = PathBuf::from(path); + tokio::spawn(async move { + if let Err(err) = tokio::fs::remove_file(&path).await { + println!("Failed to remove file {0}: {err:?}", path.to_string_lossy()); + } + }); +}