diff --git a/Cargo.lock b/Cargo.lock index 91b02054..4dc4e59f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -520,6 +520,7 @@ dependencies = [ "toml", "wasmer-runtime", "wasmer-runtime-core", + "wasmer-wasi", ] [[package]] diff --git a/examples/ipfs_node/Cargo.toml b/examples/ipfs_node/Cargo.toml index 28bb3488..c3c657f2 100644 --- a/examples/ipfs_node/Cargo.toml +++ b/examples/ipfs_node/Cargo.toml @@ -9,6 +9,7 @@ fce = { path = "../../fce" } wasmer-core = { package = "wasmer-runtime-core", version = "0.17.0", features = ["dynamicfunc-fat-closures"] } wasmer-runtime = "0.17.0" +wasmer-wasi = "0.17.0" toml = "0.5.6" serde = { version = "1.0.111", features = ["derive"] } diff --git a/examples/ipfs_node/Config.toml b/examples/ipfs_node/Config.toml index d34e4c90..286b683e 100644 --- a/examples/ipfs_node/Config.toml +++ b/examples/ipfs_node/Config.toml @@ -9,9 +9,14 @@ [core_module.wasi] envs = ["asdsad=sdaasd"] - preopened_files = ["/tmp/file1"] - mapped_dirs = { tmp = "/tmp", tmp2 = "/tmp" } + preopened_files = ["/Users/mike/dev/work/fluence/wasm/tmp/"] + mapped_dirs = { "/tmp" = "/Users/mike/dev/work/fluence/wasm/tmp" } [rpc_module] mem_pages_count = 100 logger_enabled = true + + [rpc_module.wasi] + envs = ["asdsad=sdaasd"] + preopened_files = ["/Users/mike/dev/work/fluence/wasm/tmp"] + mapped_dirs = { "/tmp/" = "/Users/mike/dev/work/fluence/wasm/tmp" } diff --git a/examples/ipfs_node/src/imports.rs b/examples/ipfs_node/src/imports.rs index c2a73d71..9a8a7807 100644 --- a/examples/ipfs_node/src/imports.rs +++ b/examples/ipfs_node/src/imports.rs @@ -25,7 +25,6 @@ use wasmer_runtime::error::ResolveError; use wasmer_core::backend::SigRegistry; use wasmer_runtime::types::LocalOrImport; use wasmer_core::module::ExportIndex; -use wasmer_core::structures::TypedIndex; const ALLOCATE_FUNC_NAME: &'static str = "allocate"; diff --git a/examples/ipfs_node/src/main.rs b/examples/ipfs_node/src/main.rs index bdc77b13..bd2db8e4 100644 --- a/examples/ipfs_node/src/main.rs +++ b/examples/ipfs_node/src/main.rs @@ -30,7 +30,7 @@ const IPFS_MODULES_DIR: &str = "/Users/mike/dev/work/fluence/wasm/fce/bin/wasm_m const IPFS_MODULES_CONFIG_PATH: &str = "/Users/mike/dev/work/fluence/wasm/fce/examples/ipfs_node/Config.toml"; -const IPFS_RPC: &str = "/Users/mike/dev/work/fluence/wasm/fce/bin/wasm_ipfs_rpc_wit.wasm"; +const IPFS_RPC: &str = "/Users/mike/dev/work/fluence/wasm/fce/bin/wasm_ipfs_rpc_wit.wasi.wasm"; fn main() { let ipfs_rpc = std::fs::read(IPFS_RPC).unwrap(); @@ -44,7 +44,7 @@ fn main() { println!("ipfs node interface is\n{}", ipfs_node.get_interface()); let result = ipfs_node - .rpc_call(&ipfs_rpc, &[IValue::String("asdsad".to_string())]) + .rpc_call(&ipfs_rpc, "put", &[IValue::String("asdsad".to_string())]) .unwrap(); println!("execution result {:?}", result); diff --git a/examples/ipfs_node/src/node.rs b/examples/ipfs_node/src/node.rs index 9da20999..3b435141 100644 --- a/examples/ipfs_node/src/node.rs +++ b/examples/ipfs_node/src/node.rs @@ -28,6 +28,7 @@ use fce::FCEModuleConfig; use std::fs; use std::path::PathBuf; +use wasmer_wasi::generate_import_object_for_version; pub struct IpfsNode { process: FCE, @@ -78,13 +79,18 @@ impl IpfsNode { }) } - pub fn rpc_call(&mut self, wasm_rpc: &[u8], args: &[IValue]) -> Result, NodeError> { + pub fn rpc_call( + &mut self, + wasm_rpc: &[u8], + func_name: &str, + args: &[IValue], + ) -> Result, NodeError> { let rpc_module_name = "ipfs_rpc"; self.process .load_module(rpc_module_name, wasm_rpc, self.rpc_module_config.clone())?; - let call_result = self.process.call(rpc_module_name, "invoke", args)?; + let call_result = self.process.call(rpc_module_name, func_name, args)?; self.process.unload_module(rpc_module_name)?; Ok(call_result) @@ -110,6 +116,7 @@ impl IpfsNode { use crate::imports::create_host_import_func; use crate::imports::log_utf8_string; use wasmer_core::import::Namespace; + use wasmer_wasi::WasiVersion; let mut wasm_module_config = FCEModuleConfig::default(); @@ -137,10 +144,7 @@ impl IpfsNode { } } - let mut import_object = ImportObject::new(); - import_object.register("host", namespace); - - if let Some(wasi) = module_config.wasi { + let mut import_object = if let Some(wasi) = module_config.wasi { if let Some(envs) = wasi.envs { wasm_module_config.wasi_envs = envs; } @@ -158,9 +162,22 @@ impl IpfsNode { .map(|(from, to)| (from, PathBuf::from(to))) .collect::>(); } - } + + generate_import_object_for_version( + WasiVersion::Latest, + vec![], + wasm_module_config.wasi_envs.clone(), + wasm_module_config.wasi_preopened_files.clone(), + wasm_module_config.wasi_mapped_dirs.clone(), + ) + } else { + ImportObject::new() + }; + + import_object.register("host", namespace); wasm_module_config.imports = import_object; + wasm_module_config.wasi_version = WasiVersion::Latest; Ok(wasm_module_config) } diff --git a/examples/ipfs_node/wasm/ipfs_node/src/lib.rs b/examples/ipfs_node/wasm/ipfs_node/src/lib.rs index 25e1285c..d7af2cee 100644 --- a/examples/ipfs_node/wasm/ipfs_node/src/lib.rs +++ b/examples/ipfs_node/wasm/ipfs_node/src/lib.rs @@ -27,13 +27,13 @@ const RESULT_PATH: &str = "/tmp/ipfs_rpc_file"; pub unsafe fn put(file_path_ptr: *mut u8, file_path_size: usize) { let file_path = String::from_raw_parts(file_path_ptr, file_path_size, file_path_size); - let msg = format!("from Wasm ipfs_node.put: file path is {}\n", file_path); + let msg = format!("ipfs_node.put: file path is {}\n", file_path); log_utf8_string(msg.as_ptr() as _, msg.len() as _); let cmd = format!("add -Q {}", file_path); let result = ipfs(cmd.as_ptr() as _, cmd.len() as _); - let hash = if result { + let hash = if result == 1 { String::from_raw_parts( *RESULT_PTR.get_mut() as _, *RESULT_SIZE.get_mut(), @@ -43,7 +43,7 @@ pub unsafe fn put(file_path_ptr: *mut u8, file_path_size: usize) { "host ipfs call failed".to_string() }; - let msg = format!("from Wasm ipfs_node.put: file add wtih hash is {} \n", hash); + let msg = format!("ipfs_node.put: file add wtih hash is {} \n", hash); log_utf8_string(msg.as_ptr() as _, msg.len() as _); *RESULT_PTR.get_mut() = hash.as_ptr() as _; @@ -55,7 +55,7 @@ pub unsafe fn put(file_path_ptr: *mut u8, file_path_size: usize) { pub unsafe fn get(hash_ptr: *mut u8, hash_size: usize) { let hash = String::from_raw_parts(hash_ptr, hash_size, hash_size); - let msg = format!("from Wasm ipfs_node.get: file hash is {}\n", hash); + let msg = format!("ipfs_node.get: file hash is {}\n", hash); log_utf8_string(msg.as_ptr() as _, msg.len() as _); let cmd = format!("get -o {} {}", RESULT_PATH, hash); @@ -70,7 +70,7 @@ pub unsafe fn get(hash_ptr: *mut u8, hash_size: usize) { // TODO: check output let file_path = RESULT_PATH.to_string(); - let msg = format!("from Wasm ipfs_node.get: file path is {}", file_path); + let msg = format!("ipfs_node.get: file path is {}", file_path); log_utf8_string(msg.as_ptr() as _, msg.len() as _); *RESULT_PTR.get_mut() = file_path.as_ptr() as _; diff --git a/examples/ipfs_node/wasm/ipfs_node/src/mem.rs b/examples/ipfs_node/wasm/ipfs_node/src/mem.rs index a9fc45d6..70172235 100644 --- a/examples/ipfs_node/wasm/ipfs_node/src/mem.rs +++ b/examples/ipfs_node/wasm/ipfs_node/src/mem.rs @@ -23,7 +23,7 @@ use std::ptr::NonNull; pub unsafe fn allocate(size: usize) -> NonNull { let layout: Layout = Layout::from_size_align(size, std::mem::align_of::()).unwrap(); - let msg = format!("wasm_node: calling allocate with {}\n", size); + let msg = format!("ipfs_node.allocate: {}\n", size); log_utf8_string(msg.as_ptr() as _, msg.len() as _); NonNull::new_unchecked(global_alloc(layout)) @@ -34,7 +34,7 @@ pub unsafe fn allocate(size: usize) -> NonNull { pub unsafe fn deallocate(ptr: NonNull, size: usize) { let layout = Layout::from_size_align(size, std::mem::align_of::()).unwrap(); - let msg = format!("wasm_node: calling deallocate with {:?} {}\n", ptr, size); + let msg = format!("ipfs_node.deallocate: {:?} {}\n", ptr, size); log_utf8_string(msg.as_ptr() as _, msg.len() as _); global_dealloc(ptr.as_ptr(), layout); diff --git a/examples/ipfs_node/wasm/ipfs_node/src/result.rs b/examples/ipfs_node/wasm/ipfs_node/src/result.rs index e294922e..b001df61 100644 --- a/examples/ipfs_node/wasm/ipfs_node/src/result.rs +++ b/examples/ipfs_node/wasm/ipfs_node/src/result.rs @@ -22,7 +22,7 @@ pub static mut RESULT_SIZE: AtomicUsize = AtomicUsize::new(0); #[no_mangle] pub unsafe fn get_result_ptr() -> usize { - let msg = "wasm_node: calling get_result_ptr\n"; + let msg = "ipfs_node.get_result_ptr\n"; log_utf8_string(msg.as_ptr() as _, msg.len() as _); *RESULT_PTR.get_mut() @@ -30,7 +30,7 @@ pub unsafe fn get_result_ptr() -> usize { #[no_mangle] pub unsafe fn get_result_size() -> usize { - let msg = "wasm_node: calling get_result_size\n"; + let msg = "ipfs_node.get_result_size\n"; log_utf8_string(msg.as_ptr() as _, msg.len() as _); *RESULT_SIZE.get_mut() @@ -38,7 +38,7 @@ pub unsafe fn get_result_size() -> usize { #[no_mangle] pub unsafe fn set_result_ptr(ptr: usize) { - let msg = format!("wasm_node: calling set_result_ptr with {}\n", ptr); + let msg = format!("ipfs_node.set_result_ptr: {}\n", ptr); log_utf8_string(msg.as_ptr() as _, msg.len() as _); *RESULT_PTR.get_mut() = ptr; @@ -46,7 +46,7 @@ pub unsafe fn set_result_ptr(ptr: usize) { #[no_mangle] pub unsafe fn set_result_size(size: usize) { - let msg = format!("wasm_node: calling set_result_size with {}\n", size); + let msg = format!("ipfs_node.set_result_size: {}\n", size); log_utf8_string(msg.as_ptr() as _, msg.len() as _); *RESULT_SIZE.get_mut() = size; diff --git a/examples/ipfs_node/wasm/ipfs_rpc/src/lib.rs b/examples/ipfs_node/wasm/ipfs_rpc/src/lib.rs index 45b33501..83b366c5 100644 --- a/examples/ipfs_node/wasm/ipfs_rpc/src/lib.rs +++ b/examples/ipfs_node/wasm/ipfs_rpc/src/lib.rs @@ -22,17 +22,33 @@ use crate::result::{RESULT_PTR, RESULT_SIZE}; use std::fs; use std::path::PathBuf; +#[no_mangle] +pub unsafe fn invoke(_ptr: *mut u8, _size: usize) { + let msg = "ipfs_rpc.invoke: invoke called"; + log_utf8_string(msg.as_ptr() as _, msg.len() as _); + + let result = "IFPFS_RPC wasm example, it allow:\nput\nget".to_string(); + + *RESULT_PTR.get_mut() = result.as_ptr() as _; + *RESULT_SIZE.get_mut() = result.len(); + std::mem::forget(result); +} + #[no_mangle] pub unsafe fn put(file_content_ptr: *mut u8, file_content_size: usize) { let file_content = String::from_raw_parts(file_content_ptr, file_content_size, file_content_size); - let msg = format!("from Wasm rpc: file_content is {}\n", file_content); + let msg = format!("ipfs_rpc.put: file_content is {}\n", file_content); log_utf8_string(msg.as_ptr() as _, msg.len() as _); let rpc_tmp_filepath = "/tmp/ipfs_rpc.tmp".to_string(); - let _ = fs::write(PathBuf::from(rpc_tmp_filepath.clone()), file_content); + let r = fs::write(PathBuf::from(rpc_tmp_filepath.clone()), file_content); + if let Err(e) = r { + let msg: String = e.to_string(); + log_utf8_string(msg.as_ptr() as _, msg.len() as _); + } ipfs_put(rpc_tmp_filepath.as_ptr() as _, rpc_tmp_filepath.len() as _); std::mem::forget(rpc_tmp_filepath); @@ -43,7 +59,7 @@ pub unsafe fn put(file_content_ptr: *mut u8, file_content_size: usize) { *RESULT_SIZE.get_mut(), ); - let msg = format!("from Wasm rpc: file add with hash {}\n", hash); + let msg = format!("ipfs_rpc.put: file add with hash {}\n", hash); log_utf8_string(msg.as_ptr() as _, msg.len() as _); *RESULT_PTR.get_mut() = hash.as_ptr() as _; @@ -55,7 +71,7 @@ pub unsafe fn put(file_content_ptr: *mut u8, file_content_size: usize) { pub unsafe fn get(hash_ptr: *mut u8, hash_size: usize) { let hash = String::from_raw_parts(hash_ptr, hash_size, hash_size); - let msg = format!("from Wasm rpc: getting file with hash {}\n", hash); + let msg = format!("ipfs_rpc.get: getting file with hash {}\n", hash); log_utf8_string(msg.as_ptr() as _, msg.len() as _); ipfs_get(hash.as_ptr() as _, hash.len() as _); @@ -66,7 +82,7 @@ pub unsafe fn get(hash_ptr: *mut u8, hash_size: usize) { *RESULT_SIZE.get_mut(), ); - let msg = format!("from Wasm rpc: reading file from {}\n", file_path); + let msg = format!("ipfs_rpc.get: reading file from {}\n", file_path); log_utf8_string(msg.as_ptr() as _, msg.len() as _); let file_content = fs::read(file_path).unwrap_or_else(|_| b"error while reading file".to_vec()); diff --git a/examples/ipfs_node/wasm/ipfs_rpc/src/mem.rs b/examples/ipfs_node/wasm/ipfs_rpc/src/mem.rs index a0f490c2..5c9fdc36 100644 --- a/examples/ipfs_node/wasm/ipfs_rpc/src/mem.rs +++ b/examples/ipfs_node/wasm/ipfs_rpc/src/mem.rs @@ -23,7 +23,7 @@ use std::ptr::NonNull; pub unsafe fn allocate(size: usize) -> NonNull { let layout: Layout = Layout::from_size_align(size, std::mem::align_of::()).unwrap(); - let msg = format!("wasm_rpc: calling allocate with {}\n", size); + let msg = format!("ipfs_rpc.allocate: {}\n", size); log_utf8_string(msg.as_ptr() as _, msg.len() as _); NonNull::new_unchecked(global_alloc(layout)) @@ -34,7 +34,7 @@ pub unsafe fn allocate(size: usize) -> NonNull { pub unsafe fn deallocate(ptr: NonNull, size: usize) { let layout = Layout::from_size_align(size, std::mem::align_of::()).unwrap(); - let msg = format!("wasm_rpc: calling deallocate with {:?} {}\n", ptr, size); + let msg = format!("ipfs_rpc.deallocate: {:?} {}\n", ptr, size); log_utf8_string(msg.as_ptr() as _, msg.len() as _); global_dealloc(ptr.as_ptr(), layout); diff --git a/examples/ipfs_node/wasm/ipfs_rpc/src/result.rs b/examples/ipfs_node/wasm/ipfs_rpc/src/result.rs index 4daf8179..d954b813 100644 --- a/examples/ipfs_node/wasm/ipfs_rpc/src/result.rs +++ b/examples/ipfs_node/wasm/ipfs_rpc/src/result.rs @@ -22,7 +22,7 @@ pub static mut RESULT_SIZE: AtomicUsize = AtomicUsize::new(0); #[no_mangle] pub unsafe fn get_result_ptr() -> usize { - let msg = "wasm_rpc: calling get_result_ptr\n"; + let msg = "ipfs_rpc.get_result_ptr\n"; log_utf8_string(msg.as_ptr() as _, msg.len() as _); *RESULT_PTR.get_mut() @@ -30,7 +30,7 @@ pub unsafe fn get_result_ptr() -> usize { #[no_mangle] pub unsafe fn get_result_size() -> usize { - let msg = "wasm_rpc: calling get_result_size\n"; + let msg = "ipfs_rpc.get_result_size\n"; log_utf8_string(msg.as_ptr() as _, msg.len() as _); *RESULT_SIZE.get_mut() @@ -38,7 +38,7 @@ pub unsafe fn get_result_size() -> usize { #[no_mangle] pub unsafe fn set_result_ptr(ptr: usize) { - let msg = format!("wasm_rpc: calling set_result_ptr with {}\n", ptr); + let msg = format!("ipfs_rpc.set_result_ptr: {}\n", ptr); log_utf8_string(msg.as_ptr() as _, msg.len() as _); *RESULT_PTR.get_mut() = ptr; @@ -46,7 +46,7 @@ pub unsafe fn set_result_ptr(ptr: usize) { #[no_mangle] pub unsafe fn set_result_size(size: usize) { - let msg = format!("wasm_rpc: calling set_result_size with {}\n", size); + let msg = format!("ipfs_rpc.set_result_size: {}\n", size); log_utf8_string(msg.as_ptr() as _, msg.len() as _); *RESULT_SIZE.get_mut() = size; diff --git a/examples/ipfs_node/wasm/ipfs_rpc/wit b/examples/ipfs_node/wasm/ipfs_rpc/wit index 38b831c0..8026c16f 100644 --- a/examples/ipfs_node/wasm/ipfs_rpc/wit +++ b/examples/ipfs_node/wasm/ipfs_rpc/wit @@ -26,10 +26,16 @@ (@interface type (func (param string) (result string))) ;; 8 ;; import ipfs put/get function -(@interface type (func (param i32 i32))) ;; 9 +(@interface type (func (param i32 i32))) ;; 9 ;; import ipfs put/get function -(@interface type (func (param i32 i32))) ;; 10 +(@interface type (func (param i32 i32))) ;; 10 + +;; export ipfs put/get function +(@interface type (func (param string) (result string))) ;; 11 + +;; export ipfs put/get function +(@interface type (func (param string) (result string))) ;; 12 (@interface export "allocate" (func 0)) ;; 0 (@interface export "deallocate" (func 1)) ;; 1 @@ -38,6 +44,8 @@ (@interface export "get_result_ptr" (func 3)) ;; 4 (@interface export "set_result_size" (func 4)) ;; 5 (@interface export "set_result_ptr" (func 4)) ;; 6 +(@interface export "put" (func 11)) ;; 7 +(@interface export "get" (func 12)) ;; 8 (@interface import "ipfs_node.wasm" "get" (func (type 5))) (@interface import "ipfs_node.wasm" "put" (func (type 6))) @@ -45,6 +53,7 @@ (@interface import "ipfs_node.wasm" "get" (func (type 7))) ;; 7 (@interface import "ipfs_node.wasm" "put" (func (type 8))) ;; 8 +;; adapter for export invoke function (@interface func (type 2) arg.get 0 string.size @@ -60,6 +69,38 @@ call-core 1 ;; call deallocate ) +;; adapter for export put function +(@interface func (type 11) + arg.get 0 + string.size + call-core 0 ;; call allocate + arg.get 0 + string.lower_memory + call-core 7 ;; call put + call-core 4 ;; call get_result_size + call-core 3 ;; call get_result_ptr + string.lift_memory + call-core 4 ;; call get_result_size + call-core 3 ;; call get_result_ptr + call-core 1 ;; call deallocate +) + +;; adapter for export get function +(@interface func (type 12) + arg.get 0 + string.size + call-core 0 ;; call allocate + arg.get 0 + string.lower_memory + call-core 8 ;; call get + call-core 4 ;; call get_result_size + call-core 3 ;; call get_result_ptr + string.lift_memory + call-core 4 ;; call get_result_size + call-core 3 ;; call get_result_ptr + call-core 1 ;; call deallocate +) + ;; adapter for import function ipfs.get (@interface func (type 9) arg.get 0 @@ -94,3 +135,5 @@ (@interface implement (func 2) (func 2)) (@interface implement (func 5) (func 9)) (@interface implement (func 6) (func 10)) +(@interface implement (func 11) (func 11)) +(@interface implement (func 12) (func 12))