diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..10ceb5d --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.DS_Store +.repl_history +/target +**/**.bak +**/**.bk +/artifacts +keypair.json diff --git a/Readme.md b/Readme.md index aba6efb..02e98cf 100644 --- a/Readme.md +++ b/Readme.md @@ -2,9 +2,51 @@ This repo holds a collection of Fluence examples and tutorials across the entire Fluence stack. If you encounter any issues or have improvement suggestions, please raise them in Issues or create a PR. +### call_parameters + +### greeting +Fluence's peer-to-peer analogy to "Hello World." + +To Do: +- [ ] Add documentation + +### ipfs-node +To Do: +- [ ] Add documentation + +### records + +To Do: +- [ ] Add documentation + +### sqlite + +To Do: +- [ ] Add documentation + + +### url-downloader + +To Do: +- [ ] Add Rust frontend + + +### ether-price-getter +ETH price getter as Fluence service from centralized CoinMarketCap. + +### fluence-cuckoo +Expose[Cuckoofilter](https://crates.io/crates/cuckoofilter) crate as a Fluence service. + +To Do: +- [x] Add documentation +- [ ] Add Rust frontend + + + + ## Contributing While the project is a still in the early stage of development, you are welcome to track progress and contribute. At the current moment we don't have detailed instructions on how to join development or which code guidelines to follow. However, you can expect more info to appear soon enough. In the meanwhile, check out the basic [contributing rules](https://github.com/fluencelabs/fluence/blob/master/CONTRIBUTING.md). ## License -Unless otherwise indicated, the applicable license is [Apache 2.0](https://github.com/fluencelabs/fluence/blob/master/LICENSE). \ No newline at end of file +Unless otherwise indicated, the applicable license is [Apache 2.0](https://github.com/fluencelabs/fluence/blob/master/LICENSE). \ No newline at end of file diff --git a/call_parameters/.gitignore b/call_parameters/.gitignore new file mode 100644 index 0000000..10ceb5d --- /dev/null +++ b/call_parameters/.gitignore @@ -0,0 +1,7 @@ +.DS_Store +.repl_history +/target +**/**.bak +**/**.bk +/artifacts +keypair.json diff --git a/call_parameters/Cargo.toml b/call_parameters/Cargo.toml new file mode 100644 index 0000000..2a75d5b --- /dev/null +++ b/call_parameters/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "call_parameters" +version = "0.1.0" +authors = ["Fluence Labs"] +edition = "2018" +publish = false + +[[bin]] +name = "call_parameters" +path = "src/main.rs" + +[dependencies] +fluence = "=0.3.2" diff --git a/call_parameters/Config.toml b/call_parameters/Config.toml new file mode 100644 index 0000000..2e3a912 --- /dev/null +++ b/call_parameters/Config.toml @@ -0,0 +1,6 @@ +modules_dir = "artifacts/" + +[[module]] + name = "call_parameters" + mem_pages_count = 1 + logger_enabled = false diff --git a/call_parameters/build.sh b/call_parameters/build.sh new file mode 100755 index 0000000..e53d222 --- /dev/null +++ b/call_parameters/build.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +cargo update +fce build --release + +rm -f artifacts/* +cp ../../target/wasm32-wasi/release/call_parameters.wasm artifacts/ diff --git a/call_parameters/src/main.rs b/call_parameters/src/main.rs new file mode 100644 index 0000000..31affbf --- /dev/null +++ b/call_parameters/src/main.rs @@ -0,0 +1,35 @@ +/* + * Copyright 2020 Fluence Labs Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#[cfg(target_arch = "wasm32")] +use fluence::fce; + +pub fn main() {} + +#[fce] +#[cfg(target_arch = "wasm32")] +pub fn call_parameters() -> String { + let cp = fluence::get_call_parameters(); + format!( + "{}\n{}\n{}\n{}\n{}\n{:?}", + cp.init_peer_id, + cp.service_id, + cp.service_creator_peer_id, + cp.host_id, + cp.particle_id, + cp.tetraplets + ) +} diff --git a/greeting/.gitignore b/greeting/.gitignore new file mode 100644 index 0000000..10ceb5d --- /dev/null +++ b/greeting/.gitignore @@ -0,0 +1,7 @@ +.DS_Store +.repl_history +/target +**/**.bak +**/**.bk +/artifacts +keypair.json diff --git a/greeting/Cargo.toml b/greeting/Cargo.toml new file mode 100644 index 0000000..98e1f70 --- /dev/null +++ b/greeting/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "wasm-greeting" +version = "0.1.0" +authors = ["Fluence Labs"] +edition = "2018" +publish = false + +[[bin]] +name = "greeting" +path = "src/main.rs" + +[dependencies] +fluence = "=0.3.2" diff --git a/greeting/Config.toml b/greeting/Config.toml new file mode 100644 index 0000000..2e740e3 --- /dev/null +++ b/greeting/Config.toml @@ -0,0 +1,6 @@ +modules_dir = "artifacts/" + +[[module]] + name = "greeting" + mem_pages_count = 1 + logger_enabled = false diff --git a/greeting/build.sh b/greeting/build.sh new file mode 100755 index 0000000..91336a7 --- /dev/null +++ b/greeting/build.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +# This script builds all subprojects and puts all created Wasm modules in one dir +cargo update +fce build --release + +rm artifacts/* +cp ../../target/wasm32-wasi/release/greeting.wasm artifacts/ diff --git a/greeting/src/main.rs b/greeting/src/main.rs new file mode 100644 index 0000000..dcf2718 --- /dev/null +++ b/greeting/src/main.rs @@ -0,0 +1,24 @@ +/* + * Copyright 2020 Fluence Labs Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use fluence::fce; + +pub fn main() {} + +#[fce] +pub fn greeting(name: String) -> String { + format!("Hi, {}", name) +} diff --git a/ipfs-node/.gitignore b/ipfs-node/.gitignore new file mode 100644 index 0000000..10ceb5d --- /dev/null +++ b/ipfs-node/.gitignore @@ -0,0 +1,7 @@ +.DS_Store +.repl_history +/target +**/**.bak +**/**.bk +/artifacts +keypair.json diff --git a/ipfs-node/Config.toml b/ipfs-node/Config.toml new file mode 100644 index 0000000..c5e30c6 --- /dev/null +++ b/ipfs-node/Config.toml @@ -0,0 +1,17 @@ +modules_dir = "artifacts/" + +[[module]] + name = "ipfs_effector" + mem_pages_count = 100 + logger_enabled = true + + [module.mounted_binaries] + ipfs = "/usr/local/bin/ipfs" + + [module.wasi] + envs = { "IPFS_ADDR" = "/dns4/relay02.fluence.dev/tcp/15001", "timeout" = "1s" } + +[[module]] + name = "ipfs_pure" + mem_pages_count = 100 + logger_enabled = true diff --git a/ipfs-node/build.sh b/ipfs-node/build.sh new file mode 100755 index 0000000..753020b --- /dev/null +++ b/ipfs-node/build.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +# This script builds all subprojects and puts all created Wasm modules in one dir +cd effector +cargo update +fce build --release +cd ../pure +cargo update +fce build --release + +cd .. +rm artifacts/* +cp ../../target/wasm32-wasi/release/ipfs_effector.wasm artifacts/ +cp ../../target/wasm32-wasi/release/ipfs_pure.wasm artifacts/ diff --git a/ipfs-node/effector/Cargo.toml b/ipfs-node/effector/Cargo.toml new file mode 100644 index 0000000..9fb038a --- /dev/null +++ b/ipfs-node/effector/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "ipfs-effector" +version = "0.1.0" +authors = ["Fluence Labs"] +edition = "2018" +publish = false + +[[bin]] +name = "ipfs_effector" +path = "src/main.rs" + +[dependencies] +fluence = { version = "=0.3.2", features = ["logger"] } +log = "0.4.11" diff --git a/ipfs-node/effector/src/main.rs b/ipfs-node/effector/src/main.rs new file mode 100644 index 0000000..53e7f38 --- /dev/null +++ b/ipfs-node/effector/src/main.rs @@ -0,0 +1,98 @@ +/* + * Copyright 2020 Fluence Labs Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#![allow(improper_ctypes)] + +mod path; + +use crate::path::to_full_path; + +use fluence::fce; +use fluence::WasmLoggerBuilder; +use fluence::MountedBinaryResult; + +const RESULT_FILE_PATH: &str = "/tmp/ipfs_rpc_file"; +const IPFS_ADDR_ENV_NAME: &str = "IPFS_ADDR"; +const TIMEOUT_ENV_NAME: &str = "timeout"; + +pub fn main() { + WasmLoggerBuilder::new() + .with_log_level(log::Level::Info) + .build() + .unwrap(); +} + +/// Put file from specified path to IPFS and return its hash. +#[fce] +pub fn put(file_path: String) -> String { + log::info!("put called with file path {}", file_path); + + let file_path = to_full_path(file_path); + + let timeout = std::env::var(TIMEOUT_ENV_NAME).unwrap_or_else(|_| "1s".to_string()); + let cmd = vec![ + String::from("add"), + String::from("--timeout"), + timeout, + String::from("-Q"), + file_path, + ]; + + let ipfs_result = unsafe { ipfs(cmd) }; + ipfs_result + .into_std() + .unwrap() + .unwrap_or_else(std::convert::identity) +} + +/// Get file by provided hash from IPFS, saves it to a temporary file and returns a path to it. +#[fce] +pub fn get(hash: String) -> String { + log::info!("get called with hash {}", hash); + + let result_file_path = to_full_path(RESULT_FILE_PATH); + + let timeout = std::env::var(TIMEOUT_ENV_NAME).unwrap_or_else(|_| "1s".to_string()); + let cmd = vec![ + String::from("get"), + String::from("--timeout"), + timeout, + String::from("-o"), + result_file_path, + hash, + ]; + + unsafe { ipfs(cmd) }; + RESULT_FILE_PATH.to_string() +} + +#[fce] +pub fn get_address() -> String { + match std::env::var(IPFS_ADDR_ENV_NAME) { + Ok(addr) => addr, + Err(e) => format!( + "getting {} env variable failed with error {:?}", + IPFS_ADDR_ENV_NAME, e + ), + } +} + +#[fce] +#[link(wasm_import_module = "host")] +extern "C" { + /// Execute provided cmd as a parameters of ipfs cli, return result. + pub fn ipfs(cmd: Vec) -> MountedBinaryResult; +} diff --git a/ipfs-node/effector/src/path.rs b/ipfs-node/effector/src/path.rs new file mode 100644 index 0000000..4f7d0d5 --- /dev/null +++ b/ipfs-node/effector/src/path.rs @@ -0,0 +1,52 @@ +/* + * Copyright 2020 Fluence Labs Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +pub(super) fn to_full_path(cmd: S) -> String +where + S: Into, +{ + use std::path::Path; + use std::path::Component; + + let cmd = cmd.into(); + let path = Path::new(&cmd); + + let mut components = path.components(); + let is_absolute = components.next() == Some(Component::RootDir); + + if !is_absolute { + return cmd; + } + + let parent = match components.next() { + Some(Component::Normal(path)) => path.to_str().unwrap(), + _ => return cmd, + }; + + match std::env::var(parent) { + Ok(to_dir) => { + let mut full_path = std::path::PathBuf::from(to_dir); + + // TODO: optimize this + #[allow(clippy::while_let_on_iterator)] + while let Some(component) = components.next() { + full_path.push(component); + } + full_path.to_string_lossy().into_owned() + } + Err(_) => cmd, + } +} diff --git a/ipfs-node/pure/Cargo.toml b/ipfs-node/pure/Cargo.toml new file mode 100644 index 0000000..ecb570c --- /dev/null +++ b/ipfs-node/pure/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "ipfs-pure" +version = "0.1.0" +authors = ["Fluence Labs"] +edition = "2018" +publish = false + +[[bin]] +name = "ipfs_pure" +path = "src/main.rs" + +[dependencies] +fluence = { version = "=0.3.2", features = ["logger"] } +log = "0.4.11" diff --git a/ipfs-node/pure/src/main.rs b/ipfs-node/pure/src/main.rs new file mode 100644 index 0000000..68c4adf --- /dev/null +++ b/ipfs-node/pure/src/main.rs @@ -0,0 +1,71 @@ +/* + * Copyright 2020 Fluence Labs Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#![allow(improper_ctypes)] + +use fluence::fce; +use fluence::WasmLoggerBuilder; + +use std::fs; +use std::path::PathBuf; + +const RPC_TMP_FILEPATH: &str = "/tmp/ipfs_rpc_file"; + +pub fn main() { + WasmLoggerBuilder::new() + .with_log_level(log::Level::Info) + .build() + .unwrap(); +} + +#[fce] +pub fn invoke() -> String { + "IPFS_RPC wasm example, it allows to:\ninvoke\nput\nget".to_string() +} + +#[fce] +pub fn put(file_content: Vec) -> String { + log::info!("put called with {:?}", file_content); + + let rpc_tmp_filepath = RPC_TMP_FILEPATH.to_string(); + + let r = fs::write(PathBuf::from(rpc_tmp_filepath.clone()), file_content); + if let Err(e) = r { + return format!("file can't be written: {}", e); + } + + unsafe { ipfs_put(rpc_tmp_filepath) } +} + +#[fce] +pub fn get(hash: String) -> Vec { + log::info!("get called with hash: {}", hash); + + let file_path = unsafe { ipfs_get(hash) }; + fs::read(file_path).unwrap_or_else(|_| b"error while reading file".to_vec()) +} + +#[fce] +#[link(wasm_import_module = "ipfs_effector")] +extern "C" { + /// Put provided file to ipfs, return ipfs hash of the file. + #[link_name = "put"] + pub fn ipfs_put(file_path: String) -> String; + + /// Get file from ipfs by hash. + #[link_name = "get"] + pub fn ipfs_get(hash: String) -> String; +} diff --git a/records/.gitignore b/records/.gitignore new file mode 100644 index 0000000..10ceb5d --- /dev/null +++ b/records/.gitignore @@ -0,0 +1,7 @@ +.DS_Store +.repl_history +/target +**/**.bak +**/**.bk +/artifacts +keypair.json diff --git a/records/Config.toml b/records/Config.toml new file mode 100644 index 0000000..cdd67f4 --- /dev/null +++ b/records/Config.toml @@ -0,0 +1,11 @@ +modules_dir = "artifacts/" + +[[module]] + name = "records_effector" + mem_pages_count = 1 + logger_enabled = true + +[[module]] + name = "records_pure" + mem_pages_count = 1 + logger_enabled = true diff --git a/records/build.sh b/records/build.sh new file mode 100755 index 0000000..0018c69 --- /dev/null +++ b/records/build.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +# This script builds all subprojects and puts all created Wasm modules in one dir +cd effector +cargo update +fce build --release +cd ../pure +cargo update +fce build --release + +cd .. +rm artifacts/* +cp ../../target/wasm32-wasi/release/records_effector.wasm artifacts/ +cp ../../target/wasm32-wasi/release/records_pure.wasm artifacts/ diff --git a/records/effector/Cargo.toml b/records/effector/Cargo.toml new file mode 100644 index 0000000..bad7246 --- /dev/null +++ b/records/effector/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "record-effector" +version = "0.1.0" +authors = ["Fluence Labs"] +edition = "2018" +publish = false + +[[bin]] +name = "records_effector" +path = "src/main.rs" + +[dependencies] +fluence = { version = "=0.3.2", features = ["logger"]} +test-record = { path = "../test-record" } diff --git a/records/effector/src/main.rs b/records/effector/src/main.rs new file mode 100644 index 0000000..9ff05b3 --- /dev/null +++ b/records/effector/src/main.rs @@ -0,0 +1,39 @@ +/* + * Copyright 2020 Fluence Labs Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use fluence::fce; +use test_record::TestRecord; + +pub fn main() {} + +#[fce] +pub fn mutate_struct(mut test_record: test_record::TestRecord) -> TestRecord { + test_record.field_0 = true; + test_record.field_1 = 1; + test_record.field_2 = 2; + test_record.field_3 = 3; + test_record.field_4 = 4; + test_record.field_5 = 5; + test_record.field_6 = 6; + test_record.field_7 = 7; + test_record.field_8 = 8; + test_record.field_9 = 9f32; + test_record.field_10 = 10f64; + test_record.field_11 = "field_11".to_string(); + test_record.field_12 = vec![0x13, 0x37]; + + test_record +} diff --git a/records/pure/Cargo.toml b/records/pure/Cargo.toml new file mode 100644 index 0000000..beea8cc --- /dev/null +++ b/records/pure/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "record-pure" +version = "0.1.0" +authors = ["Fluence Labs"] +edition = "2018" +publish = false + +[[bin]] +name = "records_pure" +path = "src/main.rs" + +[dependencies] +fluence = { version = "=0.3.2", features = ["logger"]} +test-record = { path = "../test-record" } diff --git a/records/pure/src/main.rs b/records/pure/src/main.rs new file mode 100644 index 0000000..e9c0daa --- /dev/null +++ b/records/pure/src/main.rs @@ -0,0 +1,49 @@ +/* + * Copyright 2020 Fluence Labs Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#![allow(improper_ctypes)] + +use fluence::fce; +use test_record::TestRecord; + +pub fn main() {} + +#[fce] +pub fn invoke() -> TestRecord { + let test_record = TestRecord { + field_0: false, + field_1: 0, + field_2: 0, + field_3: 0, + field_4: 0, + field_5: 0, + field_6: 0, + field_7: 0, + field_8: 0, + field_9: 0f32, + field_10: 0f64, + field_11: String::new(), + field_12: Vec::new(), + }; + + unsafe { mutate_struct(test_record) } +} + +#[fce] +#[link(wasm_import_module = "records_effector")] +extern "C" { + pub fn mutate_struct(test_record: TestRecord) -> TestRecord; +} diff --git a/records/test-record/Cargo.toml b/records/test-record/Cargo.toml new file mode 100644 index 0000000..c691357 --- /dev/null +++ b/records/test-record/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "test-record" +version = "0.1.0" +authors = ["Fluence Labs"] +edition = "2018" +publish = false + +[lib] +name = "test_record" +path = "src/test_record.rs" + +[dependencies] +fluence = "=0.3.2" diff --git a/records/test-record/src/test_record.rs b/records/test-record/src/test_record.rs new file mode 100644 index 0000000..d604149 --- /dev/null +++ b/records/test-record/src/test_record.rs @@ -0,0 +1,32 @@ +/* + * Copyright 2020 Fluence Labs Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#[fluence::fce] +pub struct TestRecord { + pub field_0: bool, + pub field_1: i8, + pub field_2: i16, + pub field_3: i32, + pub field_4: i64, + pub field_5: u8, + pub field_6: u16, + pub field_7: u32, + pub field_8: u64, + pub field_9: f32, + pub field_10: f64, + pub field_11: String, + pub field_12: Vec, +} diff --git a/sqlite/.gitignore b/sqlite/.gitignore new file mode 100644 index 0000000..10ceb5d --- /dev/null +++ b/sqlite/.gitignore @@ -0,0 +1,7 @@ +.DS_Store +.repl_history +/target +**/**.bak +**/**.bk +/artifacts +keypair.json diff --git a/sqlite/Cargo.toml b/sqlite/Cargo.toml new file mode 100644 index 0000000..bd37f3d --- /dev/null +++ b/sqlite/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "wasm-sqlite-test" +version = "0.1.0" +authors = ["Fluence Labs"] +edition = "2018" +publish = false + +[[bin]] +name = "sqlite_test" +path = "src/main.rs" + +[dependencies] +fluence = "=0.3.2" +fce-sqlite-connector = "=0.1.3" diff --git a/sqlite/Config.toml b/sqlite/Config.toml new file mode 100644 index 0000000..325d629 --- /dev/null +++ b/sqlite/Config.toml @@ -0,0 +1,13 @@ +modules_dir = "artifacts/" + +[[module]] + name = "sqlite3" + mem_pages_count = 100 + logger_enabled = false + +[[module]] +name = "sqlite_test" + mem_pages_count = 1 + logger_enabled = false + preopened_files = ["/var"] + mapped_dirs = { "var" = "./var" } diff --git a/sqlite/build.sh b/sqlite/build.sh new file mode 100755 index 0000000..6fb82fd --- /dev/null +++ b/sqlite/build.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +# This script builds all subprojects and puts all created Wasm modules in one dir +cargo update +fce build --release + +rm artifacts/* +cp ../../target/wasm32-wasi/release/sqlite_test.wasm artifacts/ +wget https://github.com/fluencelabs/sqlite/releases/download/v0.9.0_w/sqlite3.wasm +mv sqlite3.wasm artifacts/ diff --git a/sqlite/src/main.rs b/sqlite/src/main.rs new file mode 100644 index 0000000..9e5ed56 --- /dev/null +++ b/sqlite/src/main.rs @@ -0,0 +1,102 @@ +/* + * Copyright 2020 Fluence Labs Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use fluence::fce; +use fce_sqlite_connector; +use fce_sqlite_connector::State; + +pub fn main() {} + +#[fce] +pub fn test1(age: i64) { + let connection = fce_sqlite_connector::open(":memory:").unwrap(); + + connection + .execute( + " + CREATE TABLE users (name TEXT, age INTEGER); + INSERT INTO users VALUES ('Alice', 42); + INSERT INTO users VALUES ('Bob', 69); + ", + ) + .unwrap(); + + let mut statement = connection + .prepare("SELECT * FROM users WHERE age > ?") + .unwrap(); + + statement.bind(1, age).unwrap(); + + while let State::Row = statement.next().unwrap() { + println!("name = {}", statement.read::(0).unwrap()); + println!("age = {}", statement.read::(1).unwrap()); + } +} + +#[fce] +pub fn test2(age: i64) { + use fce_sqlite_connector::Value; + + let connection = fce_sqlite_connector::open(":memory:").unwrap(); + + connection + .execute( + " + CREATE TABLE users (name TEXT, age INTEGER); + INSERT INTO users VALUES ('Alice', 42); + INSERT INTO users VALUES ('Bob', 69); + ", + ) + .unwrap(); + + let mut cursor = connection + .prepare("SELECT * FROM users WHERE age > ?") + .unwrap() + .cursor(); + + cursor.bind(&[Value::Integer(age)]).unwrap(); + + while let Some(row) = cursor.next().unwrap() { + println!( + "name = {}", + row[0].as_string().expect("error on row[0] parsing") + ); + println!( + "age = {}", + row[1].as_integer().expect("error on row[1] parsing") + ); + } +} + +#[fce] +pub fn test3() { + let db_path = "/var/users.sqlite"; + let connection = fce_sqlite_connector::open(db_path).expect("error on connection establishing"); + + let execute_result = connection.execute( + " + CREATE TABLE users (name TEXT, age INTEGER); + INSERT INTO users VALUES ('Alice', 42); + INSERT INTO users VALUES ('Bob', 69); + ", + ); + + println!("execute result: {:?}", execute_result); + + //TODO fix it + // let file_size = std::fs::metadata(db_path).expect("error on file_size check").len(); + // println!("{} file size is {}", db_path, file_size); +} diff --git a/url-downloader/Config.toml b/url-downloader/Config.toml new file mode 100644 index 0000000..d22508b --- /dev/null +++ b/url-downloader/Config.toml @@ -0,0 +1,21 @@ +modules_dir = "artifacts/" + +[[module]] + name = "local_storage" + logger_enabled = true + + [module.wasi] + preopened_files = ["./sites"] + # this is where files will be stored + mapped_dirs = { "sites" = "./sites" } + +[[module]] + name = "curl_adapter" + logger_enabled = true + + [module.mounted_binaries] + curl = "/usr/bin/curl" + +[[module]] + name = "facade" + logger_enabled = true diff --git a/url-downloader/build.sh b/url-downloader/build.sh new file mode 100755 index 0000000..bacc9ad --- /dev/null +++ b/url-downloader/build.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +# This script builds all subprojects and puts all created Wasm modules in one dir +cd local_storage +cargo update +fce build --release +cd ../curl_adapter +cargo update +fce build --release +cd ../facade +cargo update +fce build --release + +cd .. +rm -f artifacts/* +cp ../../target/wasm32-wasi/release/local_storage.wasm artifacts/ +cp ../../target/wasm32-wasi/release/curl_adapter.wasm artifacts/ +cp ../../target/wasm32-wasi/release/facade.wasm artifacts/ diff --git a/url-downloader/curl_adapter/Cargo.toml b/url-downloader/curl_adapter/Cargo.toml new file mode 100644 index 0000000..bb85e9b --- /dev/null +++ b/url-downloader/curl_adapter/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "curl_adapter" +version = "0.1.0" +authors = ["Fluence Labs"] +edition = "2018" +publish = false + +[[bin]] +path = "src/main.rs" +name = "curl_adapter" + +[dependencies] +fluence = { version = "=0.3.2", features = ["logger"] } +log = "0.4.8" diff --git a/url-downloader/curl_adapter/src/main.rs b/url-downloader/curl_adapter/src/main.rs new file mode 100644 index 0000000..66df238 --- /dev/null +++ b/url-downloader/curl_adapter/src/main.rs @@ -0,0 +1,42 @@ +/* + * Copyright 2020 Fluence Labs Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#![allow(improper_ctypes)] + +use fluence::fce; + +use fluence::WasmLoggerBuilder; +use fluence::MountedBinaryResult; + +/// Log level can be changed by `RUST_LOG` env as well. +pub fn main() { + WasmLoggerBuilder::new().build().unwrap(); +} + +#[fce] +pub fn download(url: String) -> String { + log::info!("get called with url {}", url); + + let result = unsafe { curl(vec![url]) }; + String::from_utf8(result.stdout).unwrap() +} + +/// Permissions in `Config.toml` should exist to use host functions. +#[fce] +#[link(wasm_import_module = "host")] +extern "C" { + fn curl(cmd: Vec) -> MountedBinaryResult; +} diff --git a/url-downloader/facade/Cargo.toml b/url-downloader/facade/Cargo.toml new file mode 100644 index 0000000..e6de140 --- /dev/null +++ b/url-downloader/facade/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "facade" +version = "0.1.0" +authors = ["Fluence Labs"] +edition = "2018" +publish = false + +[[bin]] +name = "facade" +path = "src/main.rs" + +[dependencies] +fluence = { version = "=0.3.2", features = ["logger"]} +anyhow = "1.0.31" +log = "0.4.8" diff --git a/url-downloader/facade/src/main.rs b/url-downloader/facade/src/main.rs new file mode 100644 index 0000000..3b2fedc --- /dev/null +++ b/url-downloader/facade/src/main.rs @@ -0,0 +1,51 @@ +/* + * Copyright 2020 Fluence Labs Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#![allow(improper_ctypes)] + +use fluence::fce; +use fluence::WasmLoggerBuilder; + +pub fn main() { + WasmLoggerBuilder::new().build().unwrap(); +} + +/// Combining of modules: `curl` and `local_storage`. +/// Calls `curl` and stores returned result into a file. +#[fce] +pub fn get_n_save(url: String, file_name: String) -> String { + let result = unsafe { download(url) }; + unsafe { file_put(file_name, result.into_bytes()) }; + + String::from("Ok") +} + +/// Importing `curl` module +#[fce] +#[link(wasm_import_module = "curl_adapter")] +extern "C" { + pub fn download(url: String) -> String; +} + +/// Importing `local_storage` module +#[fce] +#[link(wasm_import_module = "local_storage")] +extern "C" { + #[link_name = "get"] + pub fn file_get(file_name: String) -> Vec; + + #[link_name = "put"] + pub fn file_put(name: String, file_content: Vec) -> String; +} diff --git a/url-downloader/local_storage/Cargo.toml b/url-downloader/local_storage/Cargo.toml new file mode 100644 index 0000000..95e5307 --- /dev/null +++ b/url-downloader/local_storage/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "local_storage" +version = "0.1.0" +authors = ["Fluence Labs"] +edition = "2018" +publish = false + +[[bin]] +name = "local_storage" +path = "src/main.rs" + +[dependencies] +fluence = { version = "=0.3.2", features = ["logger"]} +log = "0.4.8" diff --git a/url-downloader/local_storage/src/main.rs b/url-downloader/local_storage/src/main.rs new file mode 100644 index 0000000..015ddc9 --- /dev/null +++ b/url-downloader/local_storage/src/main.rs @@ -0,0 +1,51 @@ +/* + * Copyright 2020 Fluence Labs Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use std::fs; +use fluence::fce; +use fluence::WasmLoggerBuilder; +use std::path::PathBuf; + +const SITES_DIR: &str = "/sites/"; + +/// Log level can be changed by `RUST_LOG` env as well. +pub fn main() { + WasmLoggerBuilder::new().build().unwrap(); +} + +/// You can read or write files from the file system if there is permission to use directories described in `Config.toml`. +#[fce] +pub fn put(name: String, file_content: Vec) -> String { + log::info!("put called with file name {}", name); + + let rpc_tmp_filepath = format!("{}{}", SITES_DIR, name); + + let result = fs::write(PathBuf::from(rpc_tmp_filepath.clone()), file_content); + if let Err(e) = result { + return format!("file can't be written: {}", e); + } + + String::from("Ok") +} + +#[fce] +pub fn get(file_name: String) -> Vec { + log::info!("get called with file name: {}", file_name); + + let tmp_filepath = format!("{}{}", SITES_DIR, file_name); + + fs::read(tmp_filepath).unwrap_or_else(|_| b"error while reading file".to_vec()) +}