Skip to content

Commit

Permalink
Merge pull request #9 from wetware/feat/wasm_load
Browse files Browse the repository at this point in the history
Merge WASM PoC
  • Loading branch information
mikelsr authored Aug 14, 2024
2 parents 4744236 + 791166e commit 9fd27d2
Show file tree
Hide file tree
Showing 19 changed files with 232 additions and 56 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Web Assembly files
*.wasm


# Generated by Cargo
# will have compiled files and executables
debug/
Expand Down
10 changes: 6 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[workspace]
members = ["ww_net", "ww_proc"]
members = ["lib/net", "lib/proc"]

[dependencies]
anyhow = "1"
clap = { version = "4.5.13", features = ["derive"] }
futures = "0.3.29"
ipfs-api-backend-hyper = "0.6"
libp2p = { version = "0.53.2", features = ["full"] }
libp2p = { version = "0.54.0", features = ["full"] }
rand = "0.8"
tokio = { version = "1.36", features = ["full"] }
tokio = { version = "1.x", features = ["full"] }
tracing = "0.1.37"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
ww_net = { path = "ww_net" }
net = { path = "lib/net" }
proc = { path = "lib/proc" }
7 changes: 5 additions & 2 deletions ww_net/Cargo.toml → lib/net/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
[package]
name = "ww_net"
name = "net"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
anyhow = "1"
bytes = "1.7.1"
futures = "0.3.29"
libp2p = { version = "0.53.2", features = ["full"] }
ipfs-api-backend-hyper = "0.6.0"
ipfs-api-prelude = "0.6.0"
libp2p = { version = "0.54.0", features = ["full"] }
rand = "0.8"
tokio = { version = "1.36", features = ["full"] }
tracing = "0.1.37"
Expand Down
File renamed without changes.
22 changes: 22 additions & 0 deletions lib/net/src/ipfs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use bytes::Bytes;
use ipfs_api_backend_hyper::{Error, IpfsApi, IpfsClient, TryFromUri};
use ipfs_api_prelude::BoxStream;
use libp2p::Multiaddr;

// TODO rename and move to ipfs file
pub struct Client {
client: IpfsClient,
}

impl Client {
pub fn new(addr: Multiaddr) -> Self {
Self {
client: IpfsClient::from_multiaddr_str(addr.to_string().as_str())
.expect("error initializing IPFS client"),
}
}

pub fn get_file(&self, path: String) -> BoxStream<Bytes, Error> {
self.client.cat(path.as_str())
}
}
5 changes: 3 additions & 2 deletions ww_net/src/lib.rs → lib/net/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod net;
pub mod dial;
pub mod ipfs;

use core::ops::{Deref, DerefMut};

Expand Down Expand Up @@ -31,7 +32,7 @@ impl DerefMut for DefaultSwarm {
}
}

impl net::Dialer for DefaultSwarm {
impl dial::Dialer for DefaultSwarm {
// Forward the call to the inner Swarm.
fn dial(&mut self, opts: swarm::dial_opts::DialOpts) -> Result<(), swarm::DialError> {
self.0.dial(opts)
Expand Down
26 changes: 26 additions & 0 deletions lib/proc/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[package]
name = "proc"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
uuid = { version = "1.10.0", features = [
"v4", # Lets you generate random UUIDs
"fast-rng", # Use a faster (but still sufficiently random) RNG
"macro-diagnostics", # Enable better diagnostics for compile-time UUIDs
] }
wasmer = { version = "4.x" }

wasmer-wasix = { version = "0.24", default-features = false, features = [
"chrono",
"compiler",
"journal",
"reqwest",
"sys",
"sys-poll",
"sys-thread",
"time",
] }
tracing = "0.1.37"
63 changes: 63 additions & 0 deletions lib/proc/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
use uuid::Uuid;
use wasmer::{self};
use wasmer_wasix::{WasiEnv, WasiFunctionEnv};

pub struct WasmProcess {
function: wasmer::Function,
env: WasiFunctionEnv,
}

impl WasmProcess {
pub fn new(wasi_env: WasiFunctionEnv, function: wasmer::Function) -> Self {
Self {
function: function,
env: wasi_env,
}
}

pub fn run(
&mut self,
store: &mut wasmer::Store,
) -> Result<Box<[wasmer::Value]>, wasmer::RuntimeError> {
let exit_code = self.function.call(store, &[])?;
self.env.on_exit(store, None);
Ok(exit_code)
}
}

pub struct WasmRuntime {
store: wasmer::Store,
}

impl WasmRuntime {
pub fn new() -> Self {
Self {
store: wasmer::Store::default(),
}
}

pub fn store(&mut self) -> &mut wasmer::Store {
&mut self.store
}

pub fn build(&mut self, bytecode: Vec<u8>) -> Result<WasmProcess, Box<dyn std::error::Error>> {
let module = wasmer::Module::new(&self.store, bytecode).expect("couldn't load WASM module");
let uuid = Uuid::new_v4();
let mut wasi_env = WasiEnv::builder(uuid)
// .args(&["arg1", "arg2"])
// .env("KEY", "VALUE")
.finalize(&mut self.store)?;
let import_object = wasi_env.import_object(&mut self.store, &module)?;
let instance = wasmer::Instance::new(&mut self.store, &module, &import_object)?;

// // Attach the memory export
// let memory = instance.exports.get_memory("memory")?;
// wasi_env.data_mut(&mut store).set_memory(memory.clone());

wasi_env.initialize(&mut self.store, instance.clone())?;

let function = instance.exports.get_function("_start")?;

Ok(WasmProcess::new(wasi_env, function.to_owned()))
}
}
12 changes: 6 additions & 6 deletions ww_proc/Cargo.toml → lib/rpc/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[package]
name = "ww_proc"
name = "rpc"
version = "0.1.0"
edition = "2021"

Expand All @@ -12,11 +12,11 @@ capnpc = "0.19.0"

[dependencies]
anyhow = "1"
wasmer = "4.2.8"
wasmer-compiler-cranelift = "4.2.8"
wasmer-middlewares = "4.2.8"
wasmer = "4.x"
# wasmer-compiler-cranelift = "4.2.8"
# wasmer-middlewares = "4.2.8"
futures = "0.3.0"
tokio = { version = "1.0.0", features = ["net", "rt", "macros"]}
tokio-util = { version = "0.7.4", features = ["compat"] }
# tokio = { version = "1.36", features = ["net", "rt", "macros"] }
# tokio-util = { version = "0.7.4", features = ["compat"] }
capnp = "0.19.3"
capnp-rpc = "0.19.0"
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
40 changes: 30 additions & 10 deletions src/cfg.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
use std::env;

use clap::Parser;
use libp2p::{identity, kad, Multiaddr};

/// Run a WASM program from IPFS.
#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
struct Args {
/// IPFS path of the WASM module to run, e.g.
/// '/ipfs/Qm...YR/main.wasm'.
#[arg(short, long)]
load: String,

/// Kad client (true) or server (false) mode.
#[arg(short, long, default_value_t = false)]
kad_client: bool,
}

// Configuration
pub trait Cfg {
// ID keys uniqely identifying the node.
Expand All @@ -14,12 +27,15 @@ pub trait Cfg {
fn kad_mode(&self) -> kad::Mode;
// Multiaddress the node listens on.
fn listen_addr(&self) -> Multiaddr;
// IPFS path of the WASM program to run.
fn load(&self) -> String;
// Peer ID of the node. Derived from the public key in id_keys().
fn peer_id(&self) -> identity::PeerId;
}

// Default node configuration.
pub struct DefaultCfg {
args: Args,
id_keys: identity::Keypair,
identify_protocol: String,
ipfs_addr: Multiaddr,
Expand All @@ -30,6 +46,7 @@ impl DefaultCfg {
// Default node configuration.
pub fn new() -> Self {
Self {
args: Args::parse(),
id_keys: identity::Keypair::generate_ed25519(),
identify_protocol: "/ww/identify/0.0.1".to_owned(),
ipfs_addr: "/ip4/127.0.0.1/tcp/5001".to_owned().parse().unwrap(),
Expand All @@ -39,12 +56,15 @@ impl DefaultCfg {

// Check if the node is a Kademlia client from the command-line arguments.
fn is_kad_client(&self) -> bool {
let args: Vec<String> = env::args().collect();
return args.iter().any(|arg| arg == "--kad-client");
return self.args.kad_client;
}
}

impl Cfg for DefaultCfg {
fn id_keys(&self) -> identity::Keypair {
self.id_keys.clone()
}

fn identify_protocol(&self) -> String {
self.identify_protocol.to_owned()
}
Expand All @@ -53,19 +73,19 @@ impl Cfg for DefaultCfg {
self.ipfs_addr.to_owned()
}

fn listen_addr(&self) -> Multiaddr {
self.listen_addr.to_owned()
}

fn kad_mode(&self) -> kad::Mode {
if self.is_kad_client() {
return kad::Mode::Client;
}
kad::Mode::Server
}

fn id_keys(&self) -> identity::Keypair {
self.id_keys.clone()
fn listen_addr(&self) -> Multiaddr {
self.listen_addr.to_owned()
}

fn load(&self) -> String {
self.args.load.to_owned()
}

fn peer_id(&self) -> identity::PeerId {
Expand Down
Loading

0 comments on commit 9fd27d2

Please sign in to comment.