mirror of
https://github.com/tlsnotary/tlsn.git
synced 2026-01-12 16:18:43 -05:00
Compare commits
5 Commits
dev
...
poc/wasmti
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8ed0fb6614 | ||
|
|
7bbc218ea5 | ||
|
|
f5ecf1ee79 | ||
|
|
317f9a7c9b | ||
|
|
9ecf34a8a4 |
1237
Cargo.lock
generated
1237
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -27,6 +27,8 @@ members = [
|
||||
"crates/harness/runner",
|
||||
"crates/harness/plot",
|
||||
"crates/tlsn",
|
||||
"crates/wasmtime-plugin",
|
||||
"crates/wasmtime-host",
|
||||
]
|
||||
resolver = "2"
|
||||
|
||||
|
||||
25
crates/wasmtime-host/Cargo.toml
Normal file
25
crates/wasmtime-host/Cargo.toml
Normal file
@@ -0,0 +1,25 @@
|
||||
[package]
|
||||
name = "wasmtime-host"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
android_logger = { version = "0.15.1" }
|
||||
anyhow = { workspace = true }
|
||||
async-std = { version = "1.13.2" }
|
||||
log = { workspace = true }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_json = { workspace = true }
|
||||
tokio = { workspace = true, features = ["macros", "rt-multi-thread"] }
|
||||
uniffi = { version = "0.29", features = [ "cli" ] }
|
||||
wasmtime = { git = "https://github.com/bytecodealliance/wasmtime", branch = "main", features = ["component-model-async"] }
|
||||
|
||||
[[bin]]
|
||||
name = "uniffi-bindgen"
|
||||
path = "uniffi_bindgen.rs"
|
||||
8
crates/wasmtime-host/README.md
Normal file
8
crates/wasmtime-host/README.md
Normal file
@@ -0,0 +1,8 @@
|
||||
# Info
|
||||
This crate builds a wasmtime binary to be run in Android. The binary loads and run a wasm component model plugin. UniFFI is used to generate Kotlin bindings and allow the binary's future to be driven by Android's async executor.
|
||||
|
||||
# Step
|
||||
Build this crate by running [build.sh](build.sh). The build script assumes the following to be available.
|
||||
- `aarch64-linux-android` rust target
|
||||
- [`cargo-ndk`](https://github.com/bbqsrc/cargo-ndk)
|
||||
- [`androidwasmtime`](https://github.com/tlsnotary/androidwasmtime) on the same directory level as this repo
|
||||
17
crates/wasmtime-host/build.sh
Executable file
17
crates/wasmtime-host/build.sh
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
# Build the crate to target aarch-linux-android
|
||||
cargo ndk -t arm64-v8a build --release
|
||||
|
||||
# Build FFI kotlin bindings
|
||||
cargo run --bin uniffi-bindgen generate --library ../../target/aarch64-linux-android/release/libwasmtime_host.so --language kotlin --out-dir ../../target
|
||||
|
||||
# Copy binary to android development environment (assumes androidwasmtime repo is present)
|
||||
cp ../../target/aarch64-linux-android/release/libwasmtime_host.so ../../../androidwasmtime/app/src/main/jniLibs/arm64-v8a/
|
||||
|
||||
# Copy kotlin bindings to android development environment
|
||||
cp ../../target/uniffi/wasmtime_host/wasmtime_host.kt ../../../androidwasmtime/app/src/main/java/uniffi/wasmtime/
|
||||
|
||||
echo "Binary and bindings copied to android dev env"
|
||||
87
crates/wasmtime-host/src/lib.rs
Normal file
87
crates/wasmtime-host/src/lib.rs
Normal file
@@ -0,0 +1,87 @@
|
||||
uniffi::setup_scaffolding!();
|
||||
|
||||
use std::time::Duration;
|
||||
|
||||
use android_logger::Config as LogConfig;
|
||||
use async_std::future::{pending, timeout};
|
||||
use log::{info, LevelFilter};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use wasmtime::{component::{bindgen, Component, HasSelf, Linker}, Config, Engine, Store};
|
||||
|
||||
bindgen!({
|
||||
path: "../wasmtime-plugin/wit/world.wit",
|
||||
imports: {
|
||||
"read": async,
|
||||
"write": async,
|
||||
},
|
||||
exports: {
|
||||
"main": async,
|
||||
}
|
||||
});
|
||||
|
||||
#[derive(Serialize, Debug)]
|
||||
struct Input {
|
||||
id: u8
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
struct Output {
|
||||
result: bool
|
||||
}
|
||||
|
||||
struct HostState {}
|
||||
|
||||
impl PluginImports for HostState {
|
||||
async fn read(&mut self, id: u8) -> Vec<u8> {
|
||||
info!("Id received from plugin: {id}");
|
||||
serde_json::to_vec(&format!("Hello from host {}", id)).unwrap()
|
||||
}
|
||||
|
||||
async fn write(&mut self, payload: Vec<u8>) -> Vec<u8> {
|
||||
let payload: String = serde_json::from_slice(&payload).unwrap();
|
||||
info!("Payload received from plugin: {payload}");
|
||||
let success = true;
|
||||
serde_json::to_vec(&success).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
#[uniffi::export]
|
||||
async fn main(wasm_path: &str) {
|
||||
android_logger::init_once(
|
||||
LogConfig::default()
|
||||
.with_tag("RustWasmtime")
|
||||
.with_max_level(LevelFilter::Info)
|
||||
);
|
||||
|
||||
info!("Starting wasmtime");
|
||||
|
||||
let mut config = Config::new();
|
||||
config
|
||||
.async_support(true)
|
||||
.wasm_component_model_async(true);
|
||||
|
||||
let engine = Engine::new(&config).unwrap();
|
||||
|
||||
let component = Component::from_file(&engine, wasm_path).unwrap();
|
||||
let mut linker = Linker::new(&engine);
|
||||
|
||||
Plugin::add_to_linker::<_, HasSelf<_>>(&mut linker, |state| state).unwrap();
|
||||
|
||||
let mut store = Store::new(&engine, HostState {});
|
||||
|
||||
let plugin = Plugin::instantiate_async(&mut store, &component, &linker).await.unwrap();
|
||||
|
||||
let input = Input { id: 0 };
|
||||
info!("Input: {:.?}", input);
|
||||
|
||||
// Sleep for 10s to test async capability on android host.
|
||||
info!("Sleeping for 10s...");
|
||||
let never = pending::<()>();
|
||||
timeout(Duration::from_millis(10000), never).await.unwrap_err();
|
||||
|
||||
let input_bytes = serde_json::to_vec(&input).unwrap();
|
||||
let res_byte = plugin.call_main(&mut store, &input_bytes).await.unwrap();
|
||||
let res: Output = serde_json::from_slice(&res_byte).unwrap();
|
||||
|
||||
info!("Output: {:?}", res);
|
||||
}
|
||||
3
crates/wasmtime-host/uniffi_bindgen.rs
Normal file
3
crates/wasmtime-host/uniffi_bindgen.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
fn main() {
|
||||
uniffi::uniffi_bindgen_main()
|
||||
}
|
||||
5
crates/wasmtime-plugin/.cargo/config.toml
Normal file
5
crates/wasmtime-plugin/.cargo/config.toml
Normal file
@@ -0,0 +1,5 @@
|
||||
[build]
|
||||
target = "wasm32-unknown-unknown"
|
||||
|
||||
[unstable]
|
||||
build-std = ["panic_abort", "std"]
|
||||
15
crates/wasmtime-plugin/Cargo.toml
Normal file
15
crates/wasmtime-plugin/Cargo.toml
Normal file
@@ -0,0 +1,15 @@
|
||||
[package]
|
||||
name = "wasmtime-plugin"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_json = { workspace = true }
|
||||
wit-bindgen = { version = "0.43.0" }
|
||||
8
crates/wasmtime-plugin/README.md
Normal file
8
crates/wasmtime-plugin/README.md
Normal file
@@ -0,0 +1,8 @@
|
||||
# Info
|
||||
This crate builds a wasm component model plugin. It has an async main function that calls some host functions.
|
||||
|
||||
# Step
|
||||
Build this crate by running [build.sh](build.sh). The build script assumes the following to be available.
|
||||
- `wasm32-unknown-unknown` rust target
|
||||
- [`wasm-tools`](https://github.com/bytecodealliance/wasm-tools)
|
||||
- [`androidwasmtime`](https://github.com/tlsnotary/androidwasmtime) on the same directory level as this repo
|
||||
18
crates/wasmtime-plugin/build.sh
Executable file
18
crates/wasmtime-plugin/build.sh
Executable file
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
PACKAGE_NAME="wasmtime_plugin"
|
||||
|
||||
set -e
|
||||
|
||||
# Build the project
|
||||
cargo build --release
|
||||
|
||||
# Convert the wasm binary to a component
|
||||
wasm-tools component new ../../target/wasm32-unknown-unknown/release/${PACKAGE_NAME}.wasm -o ../../target/wasm32-unknown-unknown/release/${PACKAGE_NAME}_component.wasm
|
||||
|
||||
echo "Component created: ${PACKAGE_NAME}_component.wasm"
|
||||
|
||||
# Copy component wasm to android development environment (assumes androidwasmtime repo is present)
|
||||
cp ../../target/wasm32-unknown-unknown/release/${PACKAGE_NAME}_component.wasm ../../../androidwasmtime/app/src/main/assets/plugin.wasm
|
||||
|
||||
echo "Component copied to android dev env"
|
||||
31
crates/wasmtime-plugin/src/lib.rs
Normal file
31
crates/wasmtime-plugin/src/lib.rs
Normal file
@@ -0,0 +1,31 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
wit_bindgen::generate!({
|
||||
path: "wit/world.wit",
|
||||
async: true
|
||||
});
|
||||
|
||||
struct Component;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct Input {
|
||||
id: u8
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct Output {
|
||||
result: bool
|
||||
}
|
||||
|
||||
impl Guest for Component {
|
||||
async fn main(input: Vec<u8>) -> Vec<u8> {
|
||||
let input: Input = serde_json::from_slice(&input).unwrap();
|
||||
let payload_bytes = read(input.id).await;
|
||||
let result_bytes = write(payload_bytes).await;
|
||||
let result: bool = serde_json::from_slice(&result_bytes).unwrap();
|
||||
let output = Output { result };
|
||||
serde_json::to_vec(&output).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
export!(Component);
|
||||
7
crates/wasmtime-plugin/wit/world.wit
Normal file
7
crates/wasmtime-plugin/wit/world.wit
Normal file
@@ -0,0 +1,7 @@
|
||||
package component:wasmtime-plugin;
|
||||
|
||||
world plugin {
|
||||
export main: func(input: list<u8>) -> list<u8>;
|
||||
import read: func(id: u8) -> list<u8>;
|
||||
import write: func(payload: list<u8>) -> list<u8>;
|
||||
}
|
||||
Reference in New Issue
Block a user