diff --git a/Cargo.toml b/Cargo.toml index 78a4d52..a813949 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,8 +37,8 @@ getrandom = { version = "0.2", features = ["js", "wasm-bindgen"] } [target.'cfg(target_arch = "wasm32")'.dependencies] tokio = { version = "1.29.1", default-features = false, features = ["rt"] } console_error_panic_hook = "0.1" -wasm-bindgen = { version = "0.2", features = ["serde-serialize"] } -wasm-bindgen-futures = "0.4" +wasm-bindgen = "=0.2.87" +wasm-bindgen-futures = "=0.4.37" js-sys = "0.3" web-sys = { version = "0.3", features = [ "console", diff --git a/src/blockstore.rs b/src/blockstore.rs index 2e1047e..66f53e2 100644 --- a/src/blockstore.rs +++ b/src/blockstore.rs @@ -1,46 +1,53 @@ use anyhow::Result; use async_trait::async_trait; use bytes::Bytes; + use libipld::Cid; use wnfs::common::{BlockStore, BlockStoreError}; -pub trait FFIStore: FFIStoreClone { +pub trait FFIStore<'a>: FFIStoreClone<'a> { fn get_block(&self, cid: Vec) -> Result>; fn put_block(&self, cid: Vec, bytes: Vec) -> Result<()>; } -pub trait FFIStoreClone { - fn clone_box(&self) -> Box; +pub trait FFIStoreClone<'a> { + fn clone_box(&self) -> Box + 'a>; } -impl FFIStoreClone for T +impl<'a, T> FFIStoreClone<'a> for T where - T: FFIStore + Clone + 'static, + T: 'a + FFIStore<'a> + Clone, { - fn clone_box(&self) -> Box { + fn clone_box(&self) -> Box + 'a> { Box::new(self.clone()) } } -impl Clone for Box { - fn clone(&self) -> Box { +impl<'a> Clone for Box + 'a> { + fn clone(&self) -> Box + 'a> { self.clone_box() } } #[derive(Clone)] -pub struct FFIFriendlyBlockStore { - pub ffi_store: Box, +pub struct FFIFriendlyBlockStore<'a> { + pub ffi_store: Box + 'a>, } -impl FFIFriendlyBlockStore { - pub fn new(ffi_store: Box) -> Self { +//-------------------------------------------------------------------------------------------------- +// Implementations +//-------------------------------------------------------------------------------------------------- + +impl<'a> FFIFriendlyBlockStore<'a> { + /// Creates a new kv block store. + pub fn new(ffi_store: Box + 'a>) -> Self { Self { ffi_store } } } #[async_trait(?Send)] -impl BlockStore for FFIFriendlyBlockStore { +impl<'a> BlockStore for FFIFriendlyBlockStore<'a> { + /// Retrieves an array of bytes from the block store with given CID. async fn get_block(&self, cid: &Cid) -> Result { let bytes = self .ffi_store @@ -49,6 +56,7 @@ impl BlockStore for FFIFriendlyBlockStore { Ok(Bytes::copy_from_slice(&bytes)) } + /// Stores an array of bytes in the block store. async fn put_block(&self, bytes: impl Into, codec: u64) -> Result { let data: Bytes = bytes.into(); @@ -69,5 +77,9 @@ impl BlockStore for FFIFriendlyBlockStore { } } +//-------------------------------------------------------------------------------------------------- +// Functions +//-------------------------------------------------------------------------------------------------- + #[cfg(test)] mod blockstore_tests; \ No newline at end of file diff --git a/src/kvstore.rs b/src/kvstore.rs index f59ee1d..740be86 100644 --- a/src/kvstore.rs +++ b/src/kvstore.rs @@ -29,7 +29,7 @@ impl KVBlockStore { } } -impl FFIStore for KVBlockStore { +impl<'a> FFIStore<'a> for KVBlockStore { /// Retrieves an array of bytes from the block store with given CID. fn get_block(&self, cid: Vec) -> Result> { // A Bucket provides typed access to a section of the key/value store @@ -54,4 +54,4 @@ impl FFIStore for KVBlockStore { bucket.set(&key, &value)?; Ok(()) } -} +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 17c4c46..4b04fb8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,100 +1,3 @@ pub mod blockstore; pub mod kvstore; -pub mod private_forest; - -use wasm_bindgen::prelude::*; -use crate::private_forest::PrivateDirectoryHelper; -use crate::blockstore::{FFIStore, FFIFriendlyBlockStore}; -use js_sys::{Promise, Uint8Array}; -use wasm_bindgen_futures::JsFuture; - -#[wasm_bindgen] -extern "C" { - #[wasm_bindgen(typescript_type = "IStore")] - type JsStore; - - #[wasm_bindgen(method, catch)] - fn get_block(this: &JsStore, cid: Uint8Array) -> Result; - - #[wasm_bindgen(method, catch)] - fn put_block(this: &JsStore, cid: Uint8Array, bytes: Uint8Array) -> Result; -} - -#[derive(Clone)] -struct WasmStore { - inner: JsStore, -} - -impl FFIStore for WasmStore { - fn get_block(&self, cid: Vec) -> anyhow::Result> { - let js_cid = Uint8Array::from(&cid[..]); - match self.inner.get_block(js_cid) { - Ok(promise) => { - let future = async move { - let jsvalue = JsFuture::from(promise).await?; - let uint8array = Uint8Array::new(&jsvalue); - Ok(uint8array.to_vec()) - }; - - // Note: This is a simplification. You'll need proper async handling - Ok(vec![]) - } - Err(e) => Err(anyhow::anyhow!("JS Error: {:?}", e)) - } - } - - fn put_block(&self, cid: Vec, bytes: Vec) -> anyhow::Result<()> { - let js_cid = Uint8Array::from(&cid[..]); - let js_bytes = Uint8Array::from(&bytes[..]); - - match self.inner.put_block(js_cid, js_bytes) { - Ok(promise) => { - let future = async move { - JsFuture::from(promise).await?; - Ok(()) - }; - - // Note: This is a simplification. You'll need proper async handling - Ok(()) - } - Err(e) => Err(anyhow::anyhow!("JS Error: {:?}", e)) - } - } -} - -#[wasm_bindgen] -pub struct WasmPrivateDirectoryHelper { - inner: PrivateDirectoryHelper -} - -#[wasm_bindgen] -impl WasmPrivateDirectoryHelper { - #[wasm_bindgen(constructor)] - pub fn new(js_store: JsStore) -> Result { - let store = WasmStore { inner: js_store }; - let blockstore = FFIFriendlyBlockStore::new(Box::new(store)); - let wnfs_key = vec![/* your key */]; - - let helper = PrivateDirectoryHelper::synced_init(&mut blockstore, wnfs_key) - .map_err(|e| JsValue::from_str(&e))?; - - Ok(WasmPrivateDirectoryHelper { - inner: helper.0 - }) - } - - #[wasm_bindgen] - pub fn write_file(&mut self, path: String, content: Vec, mtime: i64) -> Result { - let path_segments = PrivateDirectoryHelper::parse_path(path); - self.inner.synced_write_file(&path_segments, content, mtime) - .map(|cid| cid.to_string()) - .map_err(|e| JsValue::from_str(&e)) - } - - #[wasm_bindgen] - pub fn read_file(&mut self, path: String) -> Result, JsValue> { - let path_segments = PrivateDirectoryHelper::parse_path(path); - self.inner.synced_read_file(&path_segments) - .map_err(|e| JsValue::from_str(&e)) - } -} \ No newline at end of file +pub mod private_forest; \ No newline at end of file diff --git a/src/private_forest.rs b/src/private_forest.rs index 7fdf971..89e782c 100644 --- a/src/private_forest.rs +++ b/src/private_forest.rs @@ -1,6 +1,8 @@ +//! This example shows how to add a directory to a private forest (also HAMT) which encrypts it. +//! It also shows how to retrieve encrypted nodes from the forest using `AccessKey`s. + use async_trait::async_trait; -use chrono::prelude::*; -use futures::StreamExt; +use chrono::{prelude::*, Utc}; use libipld::Cid; use rand::{rngs::ThreadRng, thread_rng}; use rand_chacha::ChaCha12Rng; @@ -11,14 +13,6 @@ use std::{ sync::Mutex, }; -// Platform-specific imports -#[cfg(not(target_arch = "wasm32"))] -use std::{ - fs::File, - io::{Read, Write}, - os::unix::fs::MetadataExt, -}; - use wnfs::{ common::{BlockStore, Metadata, CODEC_RAW}, nameaccumulator::AccumulatorSetup, @@ -33,64 +27,40 @@ use wnfs::{ use anyhow::{anyhow, Result}; use log::trace; use sha3::Sha3_256; -use crate::blockstore::FFIFriendlyBlockStore; - -// Platform-specific imports -#[cfg(not(target_arch = "wasm32"))] -use std::{ - fs::File, - io::{Read, Write}, - os::unix::fs::MetadataExt, -}; - -#[cfg(not(target_arch = "wasm32"))] -use tokio::fs::File as TokioFile; -#[cfg(not(target_arch = "wasm32"))] -use tokio::io::Result as IoResult; -#[cfg(not(target_arch = "wasm32"))] -use async_std::fs::File as AsyncFile; -#[cfg(not(target_arch = "wasm32"))] -use async_std::io::BufReader; - -#[cfg(target_arch = "wasm32")] -use web_sys::File as WebFile; - -#[cfg(target_arch = "wasm32")] -use std::io::Result as IoResult; - +use crate::blockstore::FFIFriendlyBlockStore; #[derive(Clone)] struct State { initialized: bool, wnfs_key: Vec, } - impl State { fn update(&mut self, initialized: bool, wnfs_key: Vec) { self.initialized = initialized; self.wnfs_key = wnfs_key; } } - static mut STATE: Mutex = Mutex::new(State { initialized: false, wnfs_key: Vec::new(), }); -#[derive(Clone)] -pub struct PrivateDirectoryHelper { - pub store: FFIFriendlyBlockStore, +pub struct PrivateDirectoryHelper<'a> { + pub store: FFIFriendlyBlockStore<'a>, forest: Rc, root_dir: Rc, rng: ThreadRng, } -impl PrivateDirectoryHelper { +// Single root (private ref) implementation of the wnfs private directory using KVBlockStore. +// TODO: we assumed all the write, mkdirs use same roots here. this could be done using prepend +// a root path to all path segments. +impl<'a> PrivateDirectoryHelper<'a> { async fn reload( - store: &mut FFIFriendlyBlockStore, + store: &mut FFIFriendlyBlockStore<'a>, cid: Cid, - ) -> Result { + ) -> Result, String> { let initialized: bool; let wnfs_key: Vec; unsafe { @@ -121,7 +91,7 @@ impl PrivateDirectoryHelper { async fn setup_seeded_keypair_access( forest: &mut Rc, access_key: AccessKey, - store: &mut FFIFriendlyBlockStore, + store: &mut FFIFriendlyBlockStore<'a>, seed: [u8; 32], ) -> Result<[u8; 32]> { let root_did = Self::bytes_to_hex_str(&seed); @@ -170,9 +140,9 @@ impl PrivateDirectoryHelper { } async fn init( - store: &mut FFIFriendlyBlockStore, + store: &mut FFIFriendlyBlockStore<'a>, wnfs_key: Vec, - ) -> Result<(PrivateDirectoryHelper, AccessKey, Cid), String> { + ) -> Result<(PrivateDirectoryHelper<'a>, AccessKey, Cid), String> { let rng = &mut thread_rng(); if wnfs_key.is_empty() { let err = "wnfskey is empty".to_string(); @@ -255,10 +225,10 @@ impl PrivateDirectoryHelper { } pub async fn load_with_wnfs_key( - store: &mut FFIFriendlyBlockStore, + store: &mut FFIFriendlyBlockStore<'a>, forest_cid: Cid, wnfs_key: Vec, - ) -> Result { + ) -> Result, String> { trace!("wnfsutils: load_with_wnfs_key started"); let rng = &mut thread_rng(); let root_did: String; @@ -370,7 +340,7 @@ impl PrivateDirectoryHelper { } async fn create_private_forest( - store: FFIFriendlyBlockStore, + store: FFIFriendlyBlockStore<'a>, rng: &mut ThreadRng, ) -> Result<(Rc, Cid), String> { // Do a trusted setup for WNFS' name accumulators @@ -394,7 +364,7 @@ impl PrivateDirectoryHelper { } async fn load_private_forest( - store: FFIFriendlyBlockStore, + store: FFIFriendlyBlockStore<'a>, forest_cid: Cid, ) -> Result, String> { // Deserialize private forest from the blockstore. @@ -411,7 +381,7 @@ impl PrivateDirectoryHelper { } pub async fn update_private_forest( - store: FFIFriendlyBlockStore, + store: FFIFriendlyBlockStore<'a>, forest: Rc, ) -> Result { // Serialize the private forest to DAG CBOR. @@ -428,189 +398,9 @@ impl PrivateDirectoryHelper { } } - #[cfg(not(target_arch = "wasm32"))] - fn get_file_as_byte_vec(&mut self, filename: &String) -> Result<(Vec, i64), String> { - let f = File::open(&filename); - if f.is_ok() { - let metadata_res = std::fs::metadata(&filename); - if metadata_res.is_ok() { - let metadata = metadata_res.ok().unwrap(); - let modification_time_seconds = metadata.mtime(); - - let mut buffer = vec![0; metadata.len() as usize]; - f.ok().unwrap().read(&mut buffer).expect("buffer overflow"); - Ok((buffer, modification_time_seconds)) - } else { - trace!( - "wnfsError in get_file_as_byte_vec, unable to read metadata: {:?}", - metadata_res.err().unwrap() - ); - Err("wnfsError unable to read metadata".to_string()) - } - } else { - trace!( - "wnfsError in get_file_as_byte_vec, no file found: {:?}", - f.err().unwrap() - ); - Err("wnfsError no file found".to_string()) - } - } - - #[cfg(target_arch = "wasm32")] - fn get_file_as_byte_vec(&mut self, _filename: &String) -> Result<(Vec, i64), String> { - Err("File operations not supported in WASM".to_string()) - } - - pub async fn write_file_from_path( - &mut self, - path_segments: &[String], - filename: &String, - ) -> Result { - let content: Vec; - let modification_time_seconds: i64; - let try_content = self.get_file_as_byte_vec(filename); - if try_content.is_ok() { - (content, modification_time_seconds) = try_content.ok().unwrap(); - let writefile_res = self - .write_file(path_segments, content, modification_time_seconds) - .await; - if writefile_res.is_ok() { - Ok(writefile_res.ok().unwrap()) - } else { - trace!( - "wnfsError in write_file_from_path: {:?}", - writefile_res.as_ref().err().unwrap() - ); - Err(writefile_res.err().unwrap()) - } - } else { - trace!( - "wnfsError in write_file_from_path: {:?}", - try_content.as_ref().err().unwrap() - ); - Err(try_content.err().unwrap()) - } - } - - // The new get_file_as_stream method: - #[cfg(not(target_arch = "wasm32"))] - pub async fn get_file_as_stream(&self, filename: &String) -> IoResult<(TokioFile, i64)> { - let file = TokioFile::open(filename).await?; - let metadata = tokio::fs::metadata(filename).await?; - let modified = metadata - .modified() - .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?; - let modification_time_seconds = modified - .duration_since(SystemTime::UNIX_EPOCH) - .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))? - .as_secs() as i64; - Ok((file, modification_time_seconds)) - } - - #[cfg(target_arch = "wasm32")] - pub async fn get_file_as_stream(&self, _filename: &String) -> IoResult<(WebFile, i64)> { - Err(std::io::Error::new( - std::io::ErrorKind::Unsupported, - "File operations not supported in WASM" - )) - } - - - #[cfg(not(target_arch = "wasm32"))] - pub async fn write_file_stream( - &mut self, - path_segments: &[String], - mut content: &mut BufReader, - modification_time_seconds: i64, - ) -> Result { - let filedata = async_std::fs::File::open(filename).await; - if let Ok(file) = filedata { - let metadata = file.metadata().await; - if metadata.is_err() { - return Err(format!( - "Failed to get file metadata: {:?}", - metadata.err().unwrap() - )); - } - let modification_time_seconds = metadata - .unwrap() - .modified() - .unwrap() - .duration_since(SystemTime::UNIX_EPOCH) - .unwrap() - .as_secs() as i64; - let mut reader = async_std::io::BufReader::new(file); - let writefile_res = self - .write_file_stream(path_segments, &mut reader, modification_time_seconds) - .await; - match writefile_res { - Ok(res) => Ok(res), - Err(e) => { - trace!("wnfsError in write_file_stream_from_path: {:?}", e); - Err(e.to_string()) - } - } - } else { - let e = filedata.err().unwrap(); - trace!("wnfsError in write_file_stream_from_path: {:?}", e); - Err(e.to_string()) - } - } - - #[cfg(target_arch = "wasm32")] - pub async fn write_file_stream( - &mut self, - _path_segments: &[String], - _content: &mut Vec, - _modification_time_seconds: i64, - ) -> Result { - Err("File streaming not supported in WASM".to_string()) - } - - #[cfg(not(target_arch = "wasm32"))] - fn write_byte_vec_to_file( - &mut self, - filename: &String, - file_content: Vec, - ) -> Result { - trace!("wnfs11 **********************write_byte_vec_to_file started**************filename={:?}", filename); - trace!("wnfs11 **********************write_byte_vec_to_file started**************file_content={:?}", file_content); - let file = File::create(filename); - if file.is_ok() { - let mut file_handler = file.ok().unwrap(); - trace!( - "wnfs11 **********************write_byte_vec_to_file write created**************" - ); - let write_res = file_handler.write_all(&file_content); - if write_res.is_ok() { - Ok(true) - } else { - trace!( - "wnfsError occured in write_byte_vec_to_file on write_res {:?}", - write_res.as_ref().err().unwrap().to_string() - ); - Err(write_res.err().unwrap().to_string()) - } - } else { - trace!( - "wnfsError occured in write_byte_vec_to_file on file {:?}", - file.as_ref().err().unwrap().to_string() - ); - Err(file.err().unwrap().to_string()) - } - } - - #[cfg(target_arch = "wasm32")] - fn write_byte_vec_to_file( - &mut self, - _filename: &String, - _file_content: Vec, - ) -> Result { - Err("File operations not supported in WASM".to_string()) - } - pub async fn write_file( &mut self, + path_segments: &[String], content: Vec, modification_time_seconds: i64, @@ -620,7 +410,7 @@ impl PrivateDirectoryHelper { let mut modification_time_utc: DateTime = Utc::now(); if modification_time_seconds > 0 { let naive_datetime = - NaiveDateTime::from_timestamp_opt(modification_time_seconds, 0).unwrap(); + DateTime::from_timestamp(modification_time_seconds, 0).unwrap().naive_utc(); modification_time_utc = DateTime::from_naive_utc_and_offset(naive_datetime, Utc); } let write_res = root_dir @@ -671,198 +461,6 @@ impl PrivateDirectoryHelper { } } - - pub async fn write_file_stream( - &mut self, - path_segments: &[String], - content: &mut Vec, - modification_time_seconds: i64, - ) -> Result { - let forest = &mut self.forest; - let root_dir = &mut self.root_dir; - let mut modification_time_utc: DateTime = Utc::now(); - if modification_time_seconds > 0 { - let naive_datetime = - NaiveDateTime::from_timestamp_opt(modification_time_seconds, 0).unwrap(); - modification_time_utc = DateTime::from_naive_utc_and_offset(naive_datetime, Utc); - } - - let file_open_res = root_dir - .open_file_mut( - path_segments, - true, - modification_time_utc, - forest, - &mut self.store, - &mut self.rng, - ) - .await; - if file_open_res.is_ok() { - let file = file_open_res.unwrap(); - let write_res = file - .set_content( - modification_time_utc, - content, - forest, - &mut self.store, - &mut self.rng, - ) - .await; - if write_res.is_ok() { - // Private ref contains data and keys for fetching and decrypting the directory node in the private forest. - let access_key = root_dir - .as_node() - .store(forest, &mut self.store, &mut self.rng) - .await; - if access_key.is_ok() { - let forest_cid = PrivateDirectoryHelper::update_private_forest( - self.store.to_owned(), - forest.to_owned(), - ) - .await; - if forest_cid.is_ok() { - Ok(forest_cid.ok().unwrap()) - } else { - trace!( - "wnfsError in write_file: {:?}", - forest_cid.as_ref().err().unwrap().to_string() - ); - Err(forest_cid.err().unwrap().to_string()) - } - } else { - trace!( - "wnfsError in write_file: {:?}", - access_key.as_ref().err().unwrap().to_string() - ); - Err(access_key.err().unwrap().to_string()) - } - } else { - trace!( - "wnfsError in write_file: {:?}", - write_res.as_ref().err().unwrap().to_string() - ); - Err(write_res.err().unwrap().to_string()) - } - } else { - trace!( - "wnfsError in write_file_stream: {:?}", - file_open_res.as_ref().err().unwrap().to_string() - ); - Err(file_open_res.err().unwrap().to_string()) - } - } - - #[cfg(not(target_arch = "wasm32"))] - pub async fn read_filestream_to_path( - &mut self, - local_filename: &String, - path_segments: &[String], - index: usize, - ) -> Result { - let forest = &mut self.forest; - let root_dir = &mut self.root_dir; - //let mut stream_content: Vec = vec![]; - let local_file = File::create(local_filename); - if local_file.is_ok() { - let mut local_file_handler = local_file.ok().unwrap(); - - let private_node_result = root_dir - .get_node(path_segments, true, forest, &mut self.store) - .await; - if private_node_result.is_ok() { - let result = private_node_result.ok().unwrap(); - if result.is_some() { - let private_node = result.unwrap(); - let is_file = private_node.is_file(); - if is_file { - let file_res = private_node.as_file(); - if file_res.is_ok() { - let file = file_res.ok().unwrap(); - let mut stream = file.stream_content(index, forest, &mut self.store); - while let Some(block) = stream.next().await { - if block.is_ok() { - let write_result = - local_file_handler.write_all(&block.unwrap()); - if write_result.is_err() { - trace!("wnfsError occured in read_filestream_to_path on write_result: {:?}", write_result.as_ref().err().unwrap().to_string()); - } - } else { - trace!( - "wnfsError occured in read_filestream_to_path on file_res: {:?}", - block.as_ref().err().unwrap().to_string() - ); - return Err(block.err().unwrap().to_string()); - } - //stream_content.extend_from_slice(&block.unwrap()); - } - Ok(true) - } else { - trace!( - "wnfsError occured in read_filestream_to_path on file_res: {:?}", - file_res.as_ref().err().unwrap().to_string() - ); - Err(file_res.err().unwrap().to_string()) - } - } else { - trace!("wnfsError occured in read_filestream_to_path on is_file"); - Err("wnfsError occured in read_filestream_to_path on is_file".to_string()) - } - } else { - trace!("wnfsError occured in read_filestream_to_path on result"); - Err("wnfsError occured in read_filestream_to_path on result".to_string()) - } - } else { - trace!( - "wnfsError occured in read_filestream_to_path on private_node_result: {:?}", - private_node_result.as_ref().err().unwrap().to_string() - ); - Err(private_node_result.err().unwrap().to_string()) - } - } else { - trace!( - "wnfsError occured in read_filestream_to_path on local_file {:?}", - local_file.as_ref().err().unwrap().to_string() - ); - Err(local_file.err().unwrap().to_string()) - } - } - - #[cfg(target_arch = "wasm32")] - pub async fn read_filestream_to_path( - &mut self, - _local_filename: &String, - _path_segments: &[String], - _index: usize, - ) -> Result { - Err("File operations not supported in WASM".to_string()) - } - - pub async fn read_file_to_path( - &mut self, - path_segments: &[String], - filename: &String, - ) -> Result { - let file_content_res = self.read_file(path_segments).await; - if file_content_res.is_ok() { - let res = self.write_byte_vec_to_file(filename, file_content_res.ok().unwrap()); - if res.is_ok() { - Ok(filename.to_string()) - } else { - trace!( - "wnfsError occured in read_file_to_path on res: {:?}", - res.as_ref().err().unwrap().to_string() - ); - Err(res.err().unwrap().to_string()) - } - } else { - trace!( - "wnfsError occured in read_file_to_path on file_content_res: {:?}", - file_content_res.as_ref().err().unwrap().to_string() - ); - Err(file_content_res.err().unwrap().to_string()) - } - } - pub async fn read_file(&mut self, path_segments: &[String]) -> Result, String> { let forest = &mut self.forest; let root_dir = &mut self.root_dir; @@ -1107,59 +705,53 @@ impl PrivateDirectoryHelper { } // Implement synced version of the library for using in android jni. -impl PrivateDirectoryHelper { +impl<'a> PrivateDirectoryHelper<'a> { pub fn synced_init( - store: &mut FFIFriendlyBlockStore, + store: &mut FFIFriendlyBlockStore<'a>, wnfs_key: Vec, - ) -> Result<(PrivateDirectoryHelper, AccessKey, Cid), String> { - let runtime = tokio::runtime::Runtime::new().expect("Unable to create a runtime"); + ) -> Result<(PrivateDirectoryHelper<'a>, AccessKey, Cid), String> { + let runtime = tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .expect("Unable to create a runtime"); return runtime.block_on(PrivateDirectoryHelper::init(store, wnfs_key)); } pub fn synced_load_with_wnfs_key( - store: &mut FFIFriendlyBlockStore, + store: &mut FFIFriendlyBlockStore<'a>, forest_cid: Cid, wnfs_key: Vec, - ) -> Result { - let runtime = tokio::runtime::Runtime::new().expect("Unable to create a runtime"); + ) -> Result, String> { + let runtime = tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .expect("Unable to create a runtime"); return runtime.block_on(PrivateDirectoryHelper::load_with_wnfs_key( store, forest_cid, wnfs_key, )); } pub fn synced_reload( - store: &mut FFIFriendlyBlockStore, + store: &mut FFIFriendlyBlockStore<'a>, forest_cid: Cid, - ) -> Result { - let runtime = tokio::runtime::Runtime::new().expect("Unable to create a runtime"); + ) -> Result, String> { + let runtime = tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .expect("Unable to create a runtime"); return runtime.block_on(PrivateDirectoryHelper::reload(store, forest_cid)); } - pub fn synced_write_file_from_path( - &mut self, - path_segments: &[String], - filename: &String, - ) -> Result { - let runtime = tokio::runtime::Runtime::new().expect("Unable to create a runtime"); - return runtime.block_on(self.write_file_from_path(path_segments, filename)); - } - - pub fn synced_write_file_stream_from_path( - &mut self, - path_segments: &[String], - filename: &String, - ) -> Result { - let runtime = tokio::runtime::Runtime::new().expect("Unable to create a runtime"); - return runtime.block_on(self.write_file_stream_from_path(path_segments, filename)); - } - pub fn synced_write_file( &mut self, path_segments: &[String], content: Vec, modification_time_seconds: i64, ) -> Result { - let runtime = tokio::runtime::Runtime::new().expect("Unable to create a runtime"); + let runtime = tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .expect("Unable to create a runtime"); return runtime.block_on(self.write_file( path_segments, content, @@ -1167,36 +759,19 @@ impl PrivateDirectoryHelper { )); } - pub fn synced_read_file_to_path( - &mut self, - path_segments: &[String], - filename: &String, - ) -> Result { - let runtime = tokio::runtime::Runtime::new().expect("Unable to create a runtime"); - return runtime.block_on(self.read_file_to_path(path_segments, filename)); - } - pub fn synced_read_file(&mut self, path_segments: &[String]) -> Result, String> { - let runtime = tokio::runtime::Runtime::new().expect("Unable to create a runtime"); + let runtime = tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .expect("Unable to create a runtime"); return runtime.block_on(self.read_file(path_segments)); } - pub fn synced_read_filestream_to_path( - &mut self, - local_filename: &String, - path_segments: &[String], - index: usize, - ) -> Result { - let runtime = tokio::runtime::Runtime::new().expect("Unable to create a runtime"); - return runtime.block_on(self.read_filestream_to_path( - local_filename, - path_segments, - index, - )); - } - pub fn synced_mkdir(&mut self, path_segments: &[String]) -> Result { - let runtime = tokio::runtime::Runtime::new().expect("Unable to create a runtime"); + let runtime = tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .expect("Unable to create a runtime"); return runtime.block_on(self.mkdir(path_segments)); } @@ -1205,7 +780,10 @@ impl PrivateDirectoryHelper { source_path_segments: &[String], target_path_segments: &[String], ) -> Result { - let runtime = tokio::runtime::Runtime::new().expect("Unable to create a runtime"); + let runtime = tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .expect("Unable to create a runtime"); return runtime.block_on(self.mv(source_path_segments, target_path_segments)); } @@ -1214,12 +792,18 @@ impl PrivateDirectoryHelper { source_path_segments: &[String], target_path_segments: &[String], ) -> Result { - let runtime = tokio::runtime::Runtime::new().expect("Unable to create a runtime"); + let runtime = tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .expect("Unable to create a runtime"); return runtime.block_on(self.cp(source_path_segments, target_path_segments)); } pub fn synced_rm(&mut self, path_segments: &[String]) -> Result { - let runtime = tokio::runtime::Runtime::new().expect("Unable to create a runtime"); + let runtime = tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .expect("Unable to create a runtime"); return runtime.block_on(self.rm(path_segments)); } @@ -1227,7 +811,10 @@ impl PrivateDirectoryHelper { &mut self, path_segments: &[String], ) -> Result, String> { - let runtime = tokio::runtime::Runtime::new().expect("Unable to create a runtime"); + let runtime = tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .expect("Unable to create a runtime"); return runtime.block_on(self.ls_files(path_segments)); } @@ -1286,4 +873,4 @@ impl ExchangeKey for PublicExchangeKey { } #[cfg(test)] -mod private_forest_tests; +mod private_forest_tests; \ No newline at end of file diff --git a/src/private_forest/private_forest_tests.rs b/src/private_forest/private_forest_tests.rs index f6099c0..b2c6475 100644 --- a/src/private_forest/private_forest_tests.rs +++ b/src/private_forest/private_forest_tests.rs @@ -124,11 +124,6 @@ async fn test_stream() { let mut file = File::create(filename).unwrap(); file.write_all(&vec![0u8; file_size]).unwrap(); - // Call the write method - let write_res = helper - .write_file_stream_from_path(&path_segments, &filename.to_string()) - .await; - assert!(write_res.is_ok(), "Writing the file failed!"); let read_res = helper .read_filestream_to_path(&read_filename.to_string(), &path_segments, 0) @@ -242,13 +237,6 @@ async fn test_large_file_write_stream() { let path_buf: PathBuf = tmp_file.path().to_path_buf(); let path_string: String = path_buf.to_string_lossy().into_owned(); - let path = vec!["root".into(), "file_stream1.bin".into()]; - let cid = helper - .write_file_stream_from_path(&path, &path_string) - .await - .unwrap(); - println!("cid: {:?}", cid); - println!("access_key: {:?}", access_key); let ls_result = helper.ls_files(&["root".into()]).await.unwrap(); println!("ls: {:?}", ls_result); @@ -262,13 +250,6 @@ async fn test_large_file_write_stream() { let path_buf: PathBuf = tmp_file.path().to_path_buf(); let path_string: String = path_buf.to_string_lossy().into_owned(); - let path = vec!["root".into(), "file_stream2.bin".into()]; - let cid = helper - .write_file_stream_from_path(&path, &path_string) - .await - .unwrap(); - println!("cid: {:?}", cid); - println!("access_key: {:?}", access_key); let ls_result = helper.ls_files(&["root".into()]).await.unwrap(); println!("ls: {:?}", ls_result); @@ -282,14 +263,6 @@ async fn test_large_file_write_stream() { let path_buf: PathBuf = tmp_file.path().to_path_buf(); let path_string: String = path_buf.to_string_lossy().into_owned(); - let path = vec!["root".into(), "file_stream3.bin".into()]; - let cid = helper - .write_file_stream_from_path(&path, &path_string) - .await - .unwrap(); - println!("cid: {:?}", cid); - println!("access_key: {:?}", access_key); - let ls_result = helper.ls_files(&["root".into()]).await.unwrap(); println!("ls: {:?}", ls_result); assert!(ls_result.iter().any(|item| item.0 == "file_stream3.bin")); @@ -302,14 +275,6 @@ async fn test_large_file_write_stream() { let path_buf: PathBuf = tmp_file.path().to_path_buf(); let path_string: String = path_buf.to_string_lossy().into_owned(); - let path = vec!["root".into(), "large_file_stream.bin".into()]; - let cid = helper - .write_file_stream_from_path(&path, &path_string) - .await - .unwrap(); - println!("cid: {:?}", cid); - println!("access_key: {:?}", access_key); - let ls_result = helper.ls_files(&["root".into()]).await.unwrap(); println!("ls: {:?}", ls_result); assert!(ls_result @@ -352,14 +317,6 @@ async fn test_large_file_write_stream() { let path_buf: PathBuf = tmp_file.path().to_path_buf(); let path_string: String = path_buf.to_string_lossy().into_owned(); - let path = vec!["root".into(), "large_file_stream2.bin".into()]; - let cid = helper - .write_file_stream_from_path(&path, &path_string) - .await - .unwrap(); - println!("cid: {:?}", cid); - println!("access_key: {:?}", access_key); - let ls_result = helper.ls_files(&["root".into()]).await.unwrap(); println!("ls: {:?}", ls_result); assert!(ls_result @@ -456,17 +413,6 @@ fn synced_test_large_file_write_stream() { async_std::task::block_on(async { async_std::fs::write(tmp_file.path(), &data).await.unwrap(); }); - - let path_buf: PathBuf = tmp_file.path().to_path_buf(); - let path_string: String = path_buf.to_string_lossy().into_owned(); - - let path = vec!["root".into(), format!("file_stream{}.bin", i)]; - let cid = helper - .synced_write_file_stream_from_path(&path, &path_string) - .unwrap(); - - println!("cid: {:?}", cid); - println!("access_key: {:?}", access_key); } let ls_result: Vec<(String, wnfs::common::Metadata)> = @@ -495,12 +441,6 @@ fn synced_test_large_file_write_stream() { let path_buf: PathBuf = tmp_file.path().to_path_buf(); let path_string: String = path_buf.to_string_lossy().into_owned(); - let path = vec!["root".into(), "large_file_stream.bin".into()]; - let cid = helper - .synced_write_file_stream_from_path(&path, &path_string) - .unwrap(); - println!("cid: {:?}", cid); - println!("access_key: {:?}", access_key); let ls_result = helper.synced_ls_files(&["root".into()]).unwrap(); println!("ls: {:?}", ls_result); @@ -550,13 +490,6 @@ fn synced_test_large_file_write_stream() { let path_buf: PathBuf = tmp_file.path().to_path_buf(); let path_string: String = path_buf.to_string_lossy().into_owned(); - let path = vec!["root".into(), "large_file_stream2.bin".into()]; - let cid = helper - .synced_write_file_stream_from_path(&path, &path_string) - .unwrap(); - println!("cid: {:?}", cid); - println!("access_key: {:?}", access_key); - let ls_result = helper.synced_ls_files(&["root".into()]).unwrap(); println!("ls: {:?}", ls_result); assert!(ls_result @@ -624,17 +557,6 @@ fn synced_test_large_file_write_stream() { async_std::task::block_on(async { async_std::fs::write(tmp_file.path(), &data).await.unwrap(); }); - - let path_buf: PathBuf = tmp_file.path().to_path_buf(); - let path_string: String = path_buf.to_string_lossy().into_owned(); - - let path = vec!["root".into(), format!("file_stream_reload{}.bin", i)]; - let cid = reload_helper - .synced_write_file_stream_from_path(&path, &path_string) - .unwrap(); - - println!("cid_reload: {:?}", cid); - println!("access_key_reload: {:?}", access_key); } let ls_result: Vec<(String, wnfs::common::Metadata)> = @@ -664,13 +586,6 @@ fn synced_test_large_file_write_stream() { let path_buf: PathBuf = tmp_file_reload.path().to_path_buf(); let path_string: String = path_buf.to_string_lossy().into_owned(); - let path = vec!["root".into(), "large_file_stream_reload.bin".into()]; - let cid = reload_helper - .synced_write_file_stream_from_path(&path, &path_string) - .unwrap(); - println!("cid_reload: {:?}", cid); - println!("access_key_reload: {:?}", access_key); - let ls_result = reload_helper.synced_ls_files(&["root".into()]).unwrap(); println!("ls_reload: {:?}", ls_result); assert!(ls_result @@ -747,16 +662,6 @@ fn synced_test_large_file_write_stream_with_reload() { async_std::fs::write(tmp_file.path(), &data).await.unwrap(); }); - let path_buf: PathBuf = tmp_file.path().to_path_buf(); - let path_string: String = path_buf.to_string_lossy().into_owned(); - - let path = vec!["root".into(), format!("file_stream{}.bin", i)]; - cid = reload_helper - .synced_write_file_stream_from_path(&path, &path_string) - .unwrap(); - - println!("cid: {:?}", cid); - println!("access_key: {:?}", access_key); } let reload_helper = &mut PrivateDirectoryHelper::synced_reload(blockstore, cid).unwrap(); @@ -786,14 +691,6 @@ fn synced_test_large_file_write_stream_with_reload() { let path_buf: PathBuf = tmp_file.path().to_path_buf(); let path_string: String = path_buf.to_string_lossy().into_owned(); - let path = vec!["root".into(), "large_file_stream.bin".into()]; - let reload_helper = &mut PrivateDirectoryHelper::synced_reload(blockstore, cid).unwrap(); - cid = reload_helper - .synced_write_file_stream_from_path(&path, &path_string) - .unwrap(); - println!("cid: {:?}", cid); - println!("access_key: {:?}", access_key); - let reload_helper = &mut PrivateDirectoryHelper::synced_reload(blockstore, cid).unwrap(); let ls_result = reload_helper.synced_ls_files(&["root".into()]).unwrap(); println!("ls: {:?}", ls_result); @@ -845,12 +742,6 @@ fn synced_test_large_file_write_stream_with_reload() { let path_string: String = path_buf.to_string_lossy().into_owned(); let reload_helper = &mut PrivateDirectoryHelper::synced_reload(blockstore, cid).unwrap(); - let path = vec!["root".into(), "large_file_stream2.bin".into()]; - cid = reload_helper - .synced_write_file_stream_from_path(&path, &path_string) - .unwrap(); - println!("cid: {:?}", cid); - println!("access_key: {:?}", access_key); let reload_helper = &mut PrivateDirectoryHelper::synced_reload(blockstore, cid).unwrap(); let ls_result = reload_helper.synced_ls_files(&["root".into()]).unwrap(); @@ -936,18 +827,6 @@ async fn test_large_file_write_stream_with_reload() { rand::thread_rng().fill_bytes(&mut data); let tmp_file = NamedTempFile::new().unwrap(); async_std::fs::write(tmp_file.path(), &data).await.unwrap(); - - let path_buf: PathBuf = tmp_file.path().to_path_buf(); - let path_string: String = path_buf.to_string_lossy().into_owned(); - - let path = vec!["root".into(), format!("file_stream{}.bin", i)]; - cid = reload_helper - .write_file_stream_from_path(&path, &path_string) - .await - .unwrap(); - - println!("cid: {:?}", cid); - println!("access_key: {:?}", access_key); } let reload_helper = @@ -979,17 +858,6 @@ async fn test_large_file_write_stream_with_reload() { let path_buf: PathBuf = tmp_file.path().to_path_buf(); let path_string: String = path_buf.to_string_lossy().into_owned(); - let path = vec!["root".into(), "large_file_stream.bin".into()]; - let reload_helper = - &mut PrivateDirectoryHelper::load_with_wnfs_key(blockstore, cid, empty_key.to_owned()) - .await - .unwrap(); - cid = reload_helper - .write_file_stream_from_path(&path, &path_string) - .await - .unwrap(); - println!("cid: {:?}", cid); - println!("access_key: {:?}", access_key); let ls_result = reload_helper.ls_files(&["root".into()]).await.unwrap(); println!("ls: {:?}", ls_result); assert!(ls_result @@ -1052,17 +920,6 @@ async fn test_large_file_write_stream_with_reload() { let path_buf: PathBuf = tmp_file.path().to_path_buf(); let path_string: String = path_buf.to_string_lossy().into_owned(); - let reload_helper = - &mut PrivateDirectoryHelper::load_with_wnfs_key(blockstore, cid, empty_key.to_owned()) - .await - .unwrap(); - let path = vec!["root".into(), "large_file_stream2.bin".into()]; - cid = reload_helper - .write_file_stream_from_path(&path, &path_string) - .await - .unwrap(); - println!("cid: {:?}", cid); - println!("access_key: {:?}", access_key); let reload_helper = &mut PrivateDirectoryHelper::load_with_wnfs_key(blockstore, cid, empty_key.to_owned())