Merge branch 'v0.4.0' into bp/fs2

This commit is contained in:
bitful-pannul 2023-12-13 23:44:44 -03:00
commit df5ccb6e92
48 changed files with 2151 additions and 1941 deletions

1
.gitignore vendored
View File

@ -1,4 +1,5 @@
target/ target/
uqbar
.vscode .vscode
.app-signing .app-signing
.DS_Store .DS_Store

482
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -15,7 +15,6 @@ walkdir = "2.4"
zip = "0.6" zip = "0.6"
[features] [features]
llm = []
simulation-mode = [] simulation-mode = []
[dependencies] [dependencies]
@ -63,7 +62,7 @@ rsa = "0.9"
rusoto_core = "0.48.0" rusoto_core = "0.48.0"
rusoto_s3 = "0.48.0" rusoto_s3 = "0.48.0"
rusoto_credential = "0.48.0" rusoto_credential = "0.48.0"
serde = {version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" serde_json = "1.0"
serde_urlencoded = "0.7" serde_urlencoded = "0.7"
sha2 = "0.10" sha2 = "0.10"
@ -72,10 +71,10 @@ thiserror = "1.0"
tokio = { version = "1.28", features = ["fs", "macros", "rt-multi-thread", "sync"] } tokio = { version = "1.28", features = ["fs", "macros", "rt-multi-thread", "sync"] }
tokio-tungstenite = "0.20.1" tokio-tungstenite = "0.20.1"
url = "2.4.1" url = "2.4.1"
uqbar_process_lib = { git = "ssh://git@github.com/uqbar-dao/process_lib.git", rev = "5e1b94a" } uqbar_process_lib = { git = "ssh://git@github.com/uqbar-dao/process_lib.git", rev = "3ea3a23" }
uuid = { version = "1.1.2", features = ["serde", "v4"] } uuid = { version = "1.1.2", features = ["serde", "v4"] }
warp = "0.3.5" warp = "0.3.5"
wasmtime = "14.0.4" wasmtime = "15.0.1"
wasmtime-wasi = "14.0.4" wasmtime-wasi = "15.0.1"
zip = "0.6" zip = "0.6"
rocksdb = { version = "0.21.0", features = ["multi-threaded-cf"] } rocksdb = { version = "0.21.0", features = ["multi-threaded-cf"] }

View File

@ -31,7 +31,7 @@ Get an eth-sepolia-rpc API key and pass that as an argument. You can get one for
Make sure not to use the same home directory for two nodes at once! You can use any name for the home directory: here we just use `home`. The `--` here separates cargo arguments from binary arguments. Make sure not to use the same home directory for two nodes at once! You can use any name for the home directory: here we just use `home`. The `--` here separates cargo arguments from binary arguments.
TODO: document feature flags here, `--llm` and `--simulation-mode` TODO: document feature flags `--simulation-mode`
```bash ```bash
cargo +nightly run --release -- home --rpc wss://eth-sepolia.g.alchemy.com/v2/<your-api-key> cargo +nightly run --release -- home --rpc wss://eth-sepolia.g.alchemy.com/v2/<your-api-key>
``` ```
@ -73,6 +73,6 @@ On boot you will be prompted to navigate to `localhost:8080`. Make sure your ETH
Download and install an app: Download and install an app:
``` ```
!m our@main:app_store:uqbar {"Download": {"package": {"package_name": "<pkg>", "publisher_node": "<node>"}, "install_from": "<node>"}} /m our@main:app_store:uqbar {"Download": {"package": {"package_name": "<pkg>", "publisher_node": "<node>"}, "install_from": "<node>"}}
!m our@main:app_store:uqbar {"Install": {"package_name": "<pkg>", "publisher_node": "<node>"}} /m our@main:app_store:uqbar {"Install": {"package_name": "<pkg>", "publisher_node": "<node>"}}
``` ```

42
build-release.py Executable file
View File

@ -0,0 +1,42 @@
#!/usr/bin/env python3
import os
import shutil
import subprocess
def build_and_move(feature, tmp_dir):
print("\n" + "=" * 50)
print(f"BUILDING {feature if feature else 'default'}")
print("=" * 50 + "\n")
if feature:
subprocess.run(["cargo", "+nightly", "build", "--release", "--features", feature], check=True)
binary_name = f"uqbar-{feature}"
else:
subprocess.run(["cargo", "+nightly", "build", "--release"], check=True)
binary_name = "uqbar"
# Move and rename the binary
source_path = "target/release/uqbar"
dest_path = os.path.join(tmp_dir, binary_name)
shutil.move(source_path, dest_path)
def main():
# Features to compile with
features = ["", "simulation-mode"] # Add more features as needed
# Ensure the tmp directory is clean
tmp_dir = "/tmp/uqbar-release"
if os.path.exists(tmp_dir):
shutil.rmtree(tmp_dir)
os.makedirs(tmp_dir)
# Loop through the features and build
for feature in features:
build_and_move(feature, tmp_dir)
print("Build and move process completed.\nFind release in {tmp_dir}.")
if __name__ == "__main__":
main()

View File

@ -120,9 +120,9 @@ dependencies = [
[[package]] [[package]]
name = "getrandom" name = "getrandom"
version = "0.2.10" version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
@ -131,9 +131,9 @@ dependencies = [
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.14.2" version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
[[package]] [[package]]
name = "heck" name = "heck"
@ -184,9 +184,9 @@ dependencies = [
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "1.0.9" version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
[[package]] [[package]]
name = "leb128" name = "leb128"
@ -196,9 +196,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.150" version = "0.2.151"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4"
[[package]] [[package]]
name = "log" name = "log"
@ -220,9 +220,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.69" version = "1.0.70"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
@ -268,9 +268,9 @@ dependencies = [
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.15" version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
[[package]] [[package]]
name = "semver" name = "semver"
@ -280,18 +280,18 @@ checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.191" version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a834c4821019838224821468552240d4d95d14e751986442c816572d39a080c9" checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.191" version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46fa52d5646bce91b680189fe5b1c049d2ea38dabb4e2e7c8d00ca12cfbfbcfd" checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -322,9 +322,9 @@ dependencies = [
[[package]] [[package]]
name = "smallvec" name = "smallvec"
version = "1.11.1" version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
[[package]] [[package]]
name = "spdx" name = "spdx"
@ -337,9 +337,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.39" version = "2.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" checksum = "13fa70a4ee923979ffb522cacce59d34421ebdea5625e1073c4326ef9d2dd42e"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -389,9 +389,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
[[package]] [[package]]
name = "unicode-bidi" name = "unicode-bidi"
version = "0.3.13" version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416"
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
@ -422,8 +422,8 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
[[package]] [[package]]
name = "uqbar_process_lib" name = "uqbar_process_lib"
version = "0.3.0" version = "0.4.0"
source = "git+ssh://git@github.com/uqbar-dao/process_lib.git?rev=5e1b94a#5e1b94ae2f85c66da33ec52117a72b90d53c4d22" source = "git+ssh://git@github.com/uqbar-dao/process_lib.git?rev=3ea3a23#3ea3a23de46cda8ebe1ea8f3b9f764b57e7feada"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bincode", "bincode",
@ -461,18 +461,18 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]] [[package]]
name = "wasm-encoder" name = "wasm-encoder"
version = "0.36.2" version = "0.38.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "822b645bf4f2446b949776ffca47e2af60b167209ffb70814ef8779d299cd421" checksum = "0ad2b51884de9c7f4fe2fd1043fccb8dcad4b1e29558146ee57a144d15779f3f"
dependencies = [ dependencies = [
"leb128", "leb128",
] ]
[[package]] [[package]]
name = "wasm-metadata" name = "wasm-metadata"
version = "0.10.11" version = "0.10.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2167ce53b2faa16a92c6cafd4942cff16c9a4fa0c5a5a0a41131ee4e49fc055f" checksum = "d835d67708f6374937c550ad8dd1d17c616ae009e3f00d7a0ac9f7825e78c36a"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"indexmap", "indexmap",
@ -486,9 +486,9 @@ dependencies = [
[[package]] [[package]]
name = "wasmparser" name = "wasmparser"
version = "0.116.1" version = "0.118.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a58e28b80dd8340cb07b8242ae654756161f6fc8d0038123d679b7b99964fa50" checksum = "95ee9723b928e735d53000dec9eae7b07a60e490c85ab54abb66659fc61bfcd9"
dependencies = [ dependencies = [
"indexmap", "indexmap",
"semver", "semver",
@ -496,8 +496,8 @@ dependencies = [
[[package]] [[package]]
name = "wit-bindgen" name = "wit-bindgen"
version = "0.13.1" version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"wit-bindgen-rust-macro", "wit-bindgen-rust-macro",
@ -505,8 +505,8 @@ dependencies = [
[[package]] [[package]]
name = "wit-bindgen-core" name = "wit-bindgen-core"
version = "0.13.1" version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"wit-component", "wit-component",
@ -515,8 +515,8 @@ dependencies = [
[[package]] [[package]]
name = "wit-bindgen-rust" name = "wit-bindgen-rust"
version = "0.13.2" version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"heck", "heck",
@ -527,8 +527,8 @@ dependencies = [
[[package]] [[package]]
name = "wit-bindgen-rust-macro" name = "wit-bindgen-rust-macro"
version = "0.13.1" version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"proc-macro2", "proc-macro2",
@ -541,9 +541,9 @@ dependencies = [
[[package]] [[package]]
name = "wit-component" name = "wit-component"
version = "0.17.0" version = "0.18.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "480cc1a078b305c1b8510f7c455c76cbd008ee49935f3a6c5fd5e937d8d95b1e" checksum = "5b8a35a2a9992898c9d27f1664001860595a4bc99d32dd3599d547412e17d7e2"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bitflags", "bitflags",
@ -560,9 +560,9 @@ dependencies = [
[[package]] [[package]]
name = "wit-parser" name = "wit-parser"
version = "0.12.2" version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43771ee863a16ec4ecf9da0fc65c3bbd4a1235c8e3da5f094b562894843dfa76" checksum = "15df6b7b28ce94b8be39d8df5cb21a08a4f3b9f33b631aedb4aa5776f785ead3"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"id-arena", "id-arena",

View File

@ -14,11 +14,11 @@ lto = true
anyhow = "1.0" anyhow = "1.0"
bincode = "1.3.3" bincode = "1.3.3"
rand = "0.8" rand = "0.8"
serde = {version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" serde_json = "1.0"
sha2 = "0.10.8" sha2 = "0.10.8"
uqbar_process_lib = { git = "ssh://git@github.com/uqbar-dao/process_lib.git", rev = "5e1b94a" } uqbar_process_lib = { git = "ssh://git@github.com/uqbar-dao/process_lib.git", rev = "3ea3a23" }
wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "5390bab780733f1660d14c254ec985df2816bf1d" } wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "efcc759" }
[lib] [lib]
crate-type = ["cdylib"] crate-type = ["cdylib"]

View File

@ -2,9 +2,8 @@ use serde::{Deserialize, Serialize};
use sha2::Digest; use sha2::Digest;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use uqbar_process_lib::kernel_types as kt; use uqbar_process_lib::kernel_types as kt;
use uqbar_process_lib::uqbar::process::standard as wit;
use uqbar_process_lib::{ use uqbar_process_lib::{
get_capability, get_payload, get_typed_state, grant_messaging, println, receive, set_state, await_message, get_capability, get_payload, get_typed_state, grant_messaging, println, set_state,
share_capability, Address, Message, NodeId, PackageId, ProcessId, Request, Response, share_capability, Address, Message, NodeId, PackageId, ProcessId, Request, Response,
}; };
@ -182,17 +181,15 @@ impl Guest for Component {
// active the main messaging loop: handle requests and responses // active the main messaging loop: handle requests and responses
loop { loop {
let (source, message) = match receive() { match await_message() {
Ok((source, message)) => (source, message), Err(send_error) => {
Err((error, _context)) => { println!("{our}: got network error: {send_error:?}");
// TODO handle net errors more usefully based on their context
println!("net error: {:?}", error.kind);
continue; continue;
} }
}; Ok(message) => match handle_message(&our, &mut state, &message) {
match handle_message(&our, &source, &mut state, &message) { Ok(()) => {}
Ok(()) => {} Err(e) => println!("app-store: error handling message: {:?}", e),
Err(e) => println!("app-store: error handling message: {:?}", e), }
} }
} }
} }
@ -200,18 +197,17 @@ impl Guest for Component {
fn handle_message( fn handle_message(
our: &Address, our: &Address,
source: &Address,
mut state: &mut State, mut state: &mut State,
message: &Message, message: &Message,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
match message { match message {
Message::Request(req) => { Message::Request { source, expects_response, ipc, .. } => {
match &serde_json::from_slice::<Req>(&req.ipc) { match &serde_json::from_slice::<Req>(&ipc) {
Ok(Req::LocalRequest(local_request)) => { Ok(Req::LocalRequest(local_request)) => {
match handle_local_request(&our, &source, local_request, &mut state) { match handle_local_request(&our, &source, local_request, &mut state) {
Ok(None) => return Ok(()), Ok(None) => return Ok(()),
Ok(Some(resp)) => { Ok(Some(resp)) => {
if req.expects_response.is_some() { if expects_response.is_some() {
Response::new().ipc(serde_json::to_vec(&resp)?).send()?; Response::new().ipc(serde_json::to_vec(&resp)?).send()?;
} }
} }
@ -224,7 +220,7 @@ fn handle_message(
match handle_remote_request(&our, &source, remote_request, &mut state) { match handle_remote_request(&our, &source, remote_request, &mut state) {
Ok(None) => return Ok(()), Ok(None) => return Ok(()),
Ok(Some(resp)) => { Ok(Some(resp)) => {
if req.expects_response.is_some() { if expects_response.is_some() {
Response::new().ipc(serde_json::to_vec(&resp)?).send()?; Response::new().ipc(serde_json::to_vec(&resp)?).send()?;
} }
} }
@ -259,19 +255,19 @@ fn handle_message(
} }
} }
Ok(Req::FTWorkerCommand(_)) => { Ok(Req::FTWorkerCommand(_)) => {
spawn_receive_transfer(&our, &req.ipc); spawn_receive_transfer(&our, &ipc);
} }
e => { e => {
return Err(anyhow::anyhow!( return Err(anyhow::anyhow!(
"app store bad request: {:?}, error {:?}", "app store bad request: {:?}, error {:?}",
req.ipc, ipc,
e e
)) ))
} }
} }
} }
Message::Response((response, context)) => { Message::Response { ipc, context, .. } => {
match &serde_json::from_slice::<Resp>(&response.ipc) { match &serde_json::from_slice::<Resp>(&ipc) {
Ok(Resp::RemoteResponse(remote_response)) => match remote_response { Ok(Resp::RemoteResponse(remote_response)) => match remote_response {
RemoteResponse::DownloadApproved => { RemoteResponse::DownloadApproved => {
println!("app store: download approved, should be starting"); println!("app store: download approved, should be starting");
@ -328,7 +324,7 @@ fn handle_local_request(
drive: package.to_string(), drive: package.to_string(),
action: kt::VfsAction::New, action: kt::VfsAction::New,
})?) })?)
.send_and_await_response(5)??; .send_and_await_response(5)?.unwrap();
// produce the version hash for this new package // produce the version hash for this new package
let mut hasher = sha2::Sha256::new(); let mut hasher = sha2::Sha256::new();
@ -347,7 +343,7 @@ fn handle_local_request(
}, },
})?) })?)
.payload(payload.clone()) .payload(payload.clone())
.send_and_await_response(5)??; .send_and_await_response(5)?.unwrap();
// save the zip file itself in VFS for sharing with other nodes // save the zip file itself in VFS for sharing with other nodes
// call it <package>.zip // call it <package>.zip
@ -362,14 +358,14 @@ fn handle_local_request(
}, },
})?) })?)
.payload(payload) .payload(payload)
.send_and_await_response(5)??; .send_and_await_response(5)?.unwrap();
Request::new() Request::new()
.target(Address::from_str("our@vfs:sys:uqbar")?) .target(Address::from_str("our@vfs:sys:uqbar")?)
.ipc(serde_json::to_vec(&kt::VfsRequest { .ipc(serde_json::to_vec(&kt::VfsRequest {
drive: package.to_string(), drive: package.to_string(),
action: kt::VfsAction::GetEntry("/metadata.json".into()), action: kt::VfsAction::GetEntry("/metadata.json".into()),
})?) })?)
.send_and_await_response(5)??; .send_and_await_response(5)?.unwrap();
let Some(payload) = get_payload() else { let Some(payload) = get_payload() else {
return Err(anyhow::anyhow!("no metadata found!")); return Err(anyhow::anyhow!("no metadata found!"));
}; };
@ -409,8 +405,8 @@ fn handle_local_request(
))?) ))?)
.send_and_await_response(5) .send_and_await_response(5)
{ {
Ok(Ok((_source, Message::Response((resp, _context))))) => { Ok(Ok(Message::Response { ipc, .. })) => {
let resp = serde_json::from_slice::<Resp>(&resp.ipc)?; let resp = serde_json::from_slice::<Resp>(&ipc)?;
match resp { match resp {
Resp::RemoteResponse(RemoteResponse::DownloadApproved) => { Resp::RemoteResponse(RemoteResponse::DownloadApproved) => {
state.requested_packages.insert(package.clone()); state.requested_packages.insert(package.clone());
@ -430,7 +426,7 @@ fn handle_local_request(
drive: package.to_string(), drive: package.to_string(),
action: kt::VfsAction::GetEntry("/manifest.json".into()), action: kt::VfsAction::GetEntry("/manifest.json".into()),
})?) })?)
.send_and_await_response(5)??; .send_and_await_response(5)?.unwrap();
let Some(payload) = get_payload() else { let Some(payload) = get_payload() else {
return Err(anyhow::anyhow!("no payload")); return Err(anyhow::anyhow!("no payload"));
}; };
@ -470,15 +466,15 @@ fn handle_local_request(
} else { } else {
format!("/{}", entry.process_wasm_path) format!("/{}", entry.process_wasm_path)
}; };
let (_, hash_response) = Request::new() let hash_response = Request::new()
.target(Address::from_str("our@vfs:sys:uqbar")?) .target(Address::from_str("our@vfs:sys:uqbar")?)
.ipc(serde_json::to_vec(&kt::VfsRequest { .ipc(serde_json::to_vec(&kt::VfsRequest {
drive: package.to_string(), drive: package.to_string(),
action: kt::VfsAction::GetHash(path.clone()), action: kt::VfsAction::GetHash(path.clone()),
})?) })?)
.send_and_await_response(5)??; .send_and_await_response(5)?.unwrap();
let Message::Response((wit::Response { ipc, .. }, _)) = hash_response else { let Message::Response { ipc, .. } = hash_response else {
return Err(anyhow::anyhow!("bad vfs response")); return Err(anyhow::anyhow!("bad vfs response"));
}; };
let kt::VfsResponse::GetHash(Some(hash)) = serde_json::from_slice(&ipc)? else { let kt::VfsResponse::GetHash(Some(hash)) = serde_json::from_slice(&ipc)? else {
@ -503,13 +499,13 @@ fn handle_local_request(
))?) ))?)
.send()?; .send()?;
let (_, _bytes_response) = Request::new() let _bytes_response = Request::new()
.target(Address::from_str("our@vfs:sys:uqbar")?) .target(Address::from_str("our@vfs:sys:uqbar")?)
.ipc(serde_json::to_vec(&kt::VfsRequest { .ipc(serde_json::to_vec(&kt::VfsRequest {
drive: package.to_string(), drive: package.to_string(),
action: kt::VfsAction::GetEntry(path), action: kt::VfsAction::GetEntry(path),
})?) })?)
.send_and_await_response(5)??; .send_and_await_response(5)?.unwrap();
Request::new() Request::new()
.target(Address::from_str("our@kernel:sys:uqbar")?) .target(Address::from_str("our@kernel:sys:uqbar")?)
.ipc(serde_json::to_vec(&kt::KernelCommand::InitializeProcess { .ipc(serde_json::to_vec(&kt::KernelCommand::InitializeProcess {
@ -520,7 +516,7 @@ fn handle_local_request(
public: entry.public, public: entry.public,
})?) })?)
.inherit(true) .inherit(true)
.send_and_await_response(5)?; .send_and_await_response(5)?.unwrap();
} }
for entry in &manifest { for entry in &manifest {
let process_id = ProcessId::new( let process_id = ProcessId::new(
@ -571,7 +567,7 @@ fn handle_local_request(
.ipc(serde_json::to_vec(&kt::KernelCommand::RunProcess( .ipc(serde_json::to_vec(&kt::KernelCommand::RunProcess(
process_id, process_id,
))?) ))?)
.send_and_await_response(5)?; .send_and_await_response(5)?.unwrap();
} }
Ok(Some(Resp::InstallResponse(InstallResponse::Success))) Ok(Some(Resp::InstallResponse(InstallResponse::Success)))
} }
@ -608,7 +604,7 @@ fn handle_remote_request(
drive: package.to_string(), drive: package.to_string(),
action: kt::VfsAction::GetEntry(file_name.clone()), action: kt::VfsAction::GetEntry(file_name.clone()),
})?) })?)
.send_and_await_response(5)?; .send_and_await_response(5)?.unwrap();
// transfer will inherit the payload bytes we receive from VFS // transfer will inherit the payload bytes we receive from VFS
spawn_transfer(&our, &file_name, None, &source); spawn_transfer(&our, &file_name, None, &source);
Ok(Some(Resp::RemoteResponse(RemoteResponse::DownloadApproved))) Ok(Some(Resp::RemoteResponse(RemoteResponse::DownloadApproved)))

View File

@ -71,9 +71,9 @@ dependencies = [
[[package]] [[package]]
name = "getrandom" name = "getrandom"
version = "0.2.10" version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
@ -82,9 +82,9 @@ dependencies = [
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.14.2" version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
[[package]] [[package]]
name = "heck" name = "heck"
@ -135,9 +135,9 @@ dependencies = [
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "1.0.9" version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
[[package]] [[package]]
name = "leb128" name = "leb128"
@ -147,9 +147,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.150" version = "0.2.151"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4"
[[package]] [[package]]
name = "log" name = "log"
@ -171,9 +171,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.69" version = "1.0.70"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
@ -219,9 +219,9 @@ dependencies = [
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.15" version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
[[package]] [[package]]
name = "semver" name = "semver"
@ -231,18 +231,18 @@ checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.191" version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a834c4821019838224821468552240d4d95d14e751986442c816572d39a080c9" checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.191" version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46fa52d5646bce91b680189fe5b1c049d2ea38dabb4e2e7c8d00ca12cfbfbcfd" checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -262,9 +262,9 @@ dependencies = [
[[package]] [[package]]
name = "smallvec" name = "smallvec"
version = "1.11.1" version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
[[package]] [[package]]
name = "spdx" name = "spdx"
@ -277,9 +277,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.39" version = "2.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" checksum = "13fa70a4ee923979ffb522cacce59d34421ebdea5625e1073c4326ef9d2dd42e"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -323,9 +323,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]] [[package]]
name = "unicode-bidi" name = "unicode-bidi"
version = "0.3.13" version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416"
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
@ -356,8 +356,8 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
[[package]] [[package]]
name = "uqbar_process_lib" name = "uqbar_process_lib"
version = "0.3.0" version = "0.4.0"
source = "git+ssh://git@github.com/uqbar-dao/process_lib.git?rev=5e1b94a#5e1b94ae2f85c66da33ec52117a72b90d53c4d22" source = "git+ssh://git@github.com/uqbar-dao/process_lib.git?rev=3ea3a23#3ea3a23de46cda8ebe1ea8f3b9f764b57e7feada"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bincode", "bincode",
@ -389,18 +389,18 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]] [[package]]
name = "wasm-encoder" name = "wasm-encoder"
version = "0.36.2" version = "0.38.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "822b645bf4f2446b949776ffca47e2af60b167209ffb70814ef8779d299cd421" checksum = "0ad2b51884de9c7f4fe2fd1043fccb8dcad4b1e29558146ee57a144d15779f3f"
dependencies = [ dependencies = [
"leb128", "leb128",
] ]
[[package]] [[package]]
name = "wasm-metadata" name = "wasm-metadata"
version = "0.10.11" version = "0.10.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2167ce53b2faa16a92c6cafd4942cff16c9a4fa0c5a5a0a41131ee4e49fc055f" checksum = "d835d67708f6374937c550ad8dd1d17c616ae009e3f00d7a0ac9f7825e78c36a"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"indexmap", "indexmap",
@ -414,9 +414,9 @@ dependencies = [
[[package]] [[package]]
name = "wasmparser" name = "wasmparser"
version = "0.116.1" version = "0.118.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a58e28b80dd8340cb07b8242ae654756161f6fc8d0038123d679b7b99964fa50" checksum = "95ee9723b928e735d53000dec9eae7b07a60e490c85ab54abb66659fc61bfcd9"
dependencies = [ dependencies = [
"indexmap", "indexmap",
"semver", "semver",
@ -424,8 +424,8 @@ dependencies = [
[[package]] [[package]]
name = "wit-bindgen" name = "wit-bindgen"
version = "0.13.1" version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"wit-bindgen-rust-macro", "wit-bindgen-rust-macro",
@ -433,8 +433,8 @@ dependencies = [
[[package]] [[package]]
name = "wit-bindgen-core" name = "wit-bindgen-core"
version = "0.13.1" version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"wit-component", "wit-component",
@ -443,8 +443,8 @@ dependencies = [
[[package]] [[package]]
name = "wit-bindgen-rust" name = "wit-bindgen-rust"
version = "0.13.2" version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"heck", "heck",
@ -455,8 +455,8 @@ dependencies = [
[[package]] [[package]]
name = "wit-bindgen-rust-macro" name = "wit-bindgen-rust-macro"
version = "0.13.1" version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"proc-macro2", "proc-macro2",
@ -469,9 +469,9 @@ dependencies = [
[[package]] [[package]]
name = "wit-component" name = "wit-component"
version = "0.17.0" version = "0.18.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "480cc1a078b305c1b8510f7c455c76cbd008ee49935f3a6c5fd5e937d8d95b1e" checksum = "5b8a35a2a9992898c9d27f1664001860595a4bc99d32dd3599d547412e17d7e2"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bitflags", "bitflags",
@ -488,9 +488,9 @@ dependencies = [
[[package]] [[package]]
name = "wit-parser" name = "wit-parser"
version = "0.12.2" version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43771ee863a16ec4ecf9da0fc65c3bbd4a1235c8e3da5f094b562894843dfa76" checksum = "15df6b7b28ce94b8be39d8df5cb21a08a4f3b9f33b631aedb4aa5776f785ead3"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"id-arena", "id-arena",

View File

@ -14,10 +14,10 @@ lto = true
anyhow = "1.0" anyhow = "1.0"
bincode = "1.3.3" bincode = "1.3.3"
rand = "0.8" rand = "0.8"
serde = {version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" serde_json = "1.0"
uqbar_process_lib = { git = "ssh://git@github.com/uqbar-dao/process_lib.git", rev = "5e1b94a" } uqbar_process_lib = { git = "ssh://git@github.com/uqbar-dao/process_lib.git", rev = "3ea3a23" }
wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "5390bab780733f1660d14c254ec985df2816bf1d" } wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "efcc759" }
[lib] [lib]
crate-type = ["cdylib"] crate-type = ["cdylib"]

View File

@ -1,5 +1,8 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use uqbar_process_lib::uqbar::process::standard::*; //use uqbar_process_lib::uqbar::process::standard::*;
use uqbar_process_lib::uqbar::process::standard::{Message as StdMessage, Request as StdRequest, Response as StdResponse, SendErrorKind};
use uqbar_process_lib::{await_message, get_payload, print_to_terminal, send_and_await_response, send_request, send_response, Address, Message, Payload, Request};
mod ft_worker_lib; mod ft_worker_lib;
use ft_worker_lib::*; use ft_worker_lib::*;
@ -25,11 +28,11 @@ impl Guest for Component {
let our = Address::from_str(&our).unwrap(); let our = Address::from_str(&our).unwrap();
print_to_terminal(1, &format!("{}: start", our.process)); print_to_terminal(1, &format!("{}: start", our.process));
let Ok((parent_process, Message::Request(req))) = receive() else { let Ok(Message::Request { source: parent_process, ipc, .. }) = await_message() else {
panic!("ft_worker: got bad init message"); panic!("ft_worker: got bad init message");
}; };
let command = serde_json::from_slice::<FTWorkerCommand>(&req.ipc) let command = serde_json::from_slice::<FTWorkerCommand>(&ipc)
.expect("ft_worker: got unparseable init message"); .expect("ft_worker: got unparseable init message");
match command { match command {
@ -55,7 +58,7 @@ impl Guest for Component {
// acknowledgement. // acknowledgement.
match send_and_await_response( match send_and_await_response(
&Address::from_str(&target).unwrap(), &Address::from_str(&target).unwrap(),
&Request { &StdRequest {
inherit: false, inherit: false,
expects_response: Some(timeout), expects_response: Some(timeout),
ipc: serde_json::to_vec(&FTWorkerCommand::Receive { ipc: serde_json::to_vec(&FTWorkerCommand::Receive {
@ -76,7 +79,7 @@ impl Guest for Component {
SendErrorKind::Timeout => TransferError::TargetTimeout, SendErrorKind::Timeout => TransferError::TargetTimeout,
})) }))
} }
Ok((opp_worker, Message::Response((response, _)))) => { Ok((opp_worker, StdMessage::Response((response, _)))) => {
let Ok(FTWorkerProtocol::Ready) = serde_json::from_slice(&response.ipc) else { let Ok(FTWorkerProtocol::Ready) = serde_json::from_slice(&response.ipc) else {
respond_to_parent(FTWorkerResult::Err(TransferError::TargetRejected)); respond_to_parent(FTWorkerResult::Err(TransferError::TargetRejected));
return; return;
@ -94,7 +97,7 @@ impl Guest for Component {
}; };
send_request( send_request(
&opp_worker, &opp_worker,
&Request { &StdRequest {
inherit: false, inherit: false,
expects_response: Some(timeout), expects_response: Some(timeout),
ipc: vec![], ipc: vec![],
@ -113,7 +116,7 @@ impl Guest for Component {
}; };
send_request( send_request(
&opp_worker, &opp_worker,
&Request { &StdRequest {
inherit: false, inherit: false,
expects_response: None, expects_response: None,
ipc: vec![], ipc: vec![],
@ -126,11 +129,11 @@ impl Guest for Component {
offset += chunk_size; offset += chunk_size;
} }
// now wait for Finished response // now wait for Finished response
let Ok((receiving_worker, Message::Response((resp, _)))) = receive() else { let Ok(Message::Response { source: receiving_worker, ipc, .. }) = await_message() else {
respond_to_parent(FTWorkerResult::Err(TransferError::TargetRejected)); respond_to_parent(FTWorkerResult::Err(TransferError::TargetRejected));
return; return;
}; };
let Ok(FTWorkerProtocol::Finished) = serde_json::from_slice(&resp.ipc) else { let Ok(FTWorkerProtocol::Finished) = serde_json::from_slice(&ipc) else {
respond_to_parent(FTWorkerResult::Err(TransferError::TargetRejected)); respond_to_parent(FTWorkerResult::Err(TransferError::TargetRejected));
return; return;
}; };
@ -149,7 +152,7 @@ impl Guest for Component {
} => { } => {
// send Ready response to counterparty // send Ready response to counterparty
send_response( send_response(
&Response { &StdResponse {
inherit: false, inherit: false,
ipc: serde_json::to_vec(&FTWorkerProtocol::Ready).unwrap(), ipc: serde_json::to_vec(&FTWorkerProtocol::Ready).unwrap(),
metadata: None, metadata: None,
@ -163,7 +166,7 @@ impl Guest for Component {
let mut chunks_received = 0; let mut chunks_received = 0;
let start_time = std::time::Instant::now(); let start_time = std::time::Instant::now();
loop { loop {
let Ok((source, Message::Request(req))) = receive() else { let Ok(Message::Request { .. }) = await_message() else {
respond_to_parent(FTWorkerResult::Err(TransferError::SourceFailed)); respond_to_parent(FTWorkerResult::Err(TransferError::SourceFailed));
return; return;
}; };
@ -183,7 +186,7 @@ impl Guest for Component {
} }
// send Finished message to sender // send Finished message to sender
send_response( send_response(
&Response { &StdResponse {
inherit: false, inherit: false,
ipc: serde_json::to_vec(&FTWorkerProtocol::Finished).unwrap(), ipc: serde_json::to_vec(&FTWorkerProtocol::Finished).unwrap(),
metadata: None, metadata: None,
@ -193,7 +196,7 @@ impl Guest for Component {
// send Success message to parent // send Success message to parent
send_request( send_request(
&parent_process, &parent_process,
&Request { &StdRequest {
inherit: false, inherit: false,
expects_response: None, expects_response: None,
ipc: serde_json::to_vec(&FTWorkerResult::ReceiveSuccess(file_name)) ipc: serde_json::to_vec(&FTWorkerResult::ReceiveSuccess(file_name))
@ -213,7 +216,7 @@ impl Guest for Component {
fn respond_to_parent(result: FTWorkerResult) { fn respond_to_parent(result: FTWorkerResult) {
send_response( send_response(
&Response { &StdResponse {
inherit: false, inherit: false,
ipc: serde_json::to_vec(&result).unwrap(), ipc: serde_json::to_vec(&result).unwrap(),
metadata: None, metadata: None,

103
modules/chess/Cargo.lock generated
View File

@ -64,7 +64,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]] [[package]]
name = "chess" name = "chess"
version = "0.1.0" version = "0.2.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"base64", "base64",
@ -73,6 +73,7 @@ dependencies = [
"serde", "serde",
"serde_json", "serde_json",
"uqbar_process_lib", "uqbar_process_lib",
"url",
"wit-bindgen", "wit-bindgen",
] ]
@ -138,9 +139,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]] [[package]]
name = "form_urlencoded" name = "form_urlencoded"
version = "1.2.0" version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
dependencies = [ dependencies = [
"percent-encoding", "percent-encoding",
] ]
@ -153,9 +154,9 @@ checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
[[package]] [[package]]
name = "getrandom" name = "getrandom"
version = "0.2.10" version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
@ -164,9 +165,9 @@ dependencies = [
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.14.2" version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
[[package]] [[package]]
name = "heck" name = "heck"
@ -202,9 +203,9 @@ checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005"
[[package]] [[package]]
name = "idna" name = "idna"
version = "0.4.0" version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
dependencies = [ dependencies = [
"unicode-bidi", "unicode-bidi",
"unicode-normalization", "unicode-normalization",
@ -223,9 +224,9 @@ dependencies = [
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "1.0.9" version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
@ -241,9 +242,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.150" version = "0.2.151"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4"
[[package]] [[package]]
name = "log" name = "log"
@ -278,9 +279,9 @@ dependencies = [
[[package]] [[package]]
name = "percent-encoding" name = "percent-encoding"
version = "2.3.0" version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]] [[package]]
name = "pleco" name = "pleco"
@ -304,9 +305,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.69" version = "1.0.70"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
@ -487,9 +488,9 @@ dependencies = [
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.15" version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
[[package]] [[package]]
name = "scopeguard" name = "scopeguard"
@ -505,18 +506,18 @@ checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.191" version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a834c4821019838224821468552240d4d95d14e751986442c816572d39a080c9" checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.191" version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46fa52d5646bce91b680189fe5b1c049d2ea38dabb4e2e7c8d00ca12cfbfbcfd" checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -536,9 +537,9 @@ dependencies = [
[[package]] [[package]]
name = "smallvec" name = "smallvec"
version = "1.11.1" version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
[[package]] [[package]]
name = "spdx" name = "spdx"
@ -551,9 +552,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.39" version = "2.0.41"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -597,9 +598,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]] [[package]]
name = "unicode-bidi" name = "unicode-bidi"
version = "0.3.13" version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416"
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
@ -630,8 +631,8 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
[[package]] [[package]]
name = "uqbar_process_lib" name = "uqbar_process_lib"
version = "0.3.0" version = "0.4.0"
source = "git+ssh://git@github.com/uqbar-dao/process_lib.git?rev=5e1b94a#5e1b94ae2f85c66da33ec52117a72b90d53c4d22" source = "git+ssh://git@github.com/uqbar-dao/process_lib.git?rev=c6dd31b#c6dd31bcdc3d83a1d5d4c528e390164d20f373cd"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bincode", "bincode",
@ -646,9 +647,9 @@ dependencies = [
[[package]] [[package]]
name = "url" name = "url"
version = "2.4.1" version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633"
dependencies = [ dependencies = [
"form_urlencoded", "form_urlencoded",
"idna", "idna",
@ -663,18 +664,18 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]] [[package]]
name = "wasm-encoder" name = "wasm-encoder"
version = "0.36.2" version = "0.38.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "822b645bf4f2446b949776ffca47e2af60b167209ffb70814ef8779d299cd421" checksum = "0ad2b51884de9c7f4fe2fd1043fccb8dcad4b1e29558146ee57a144d15779f3f"
dependencies = [ dependencies = [
"leb128", "leb128",
] ]
[[package]] [[package]]
name = "wasm-metadata" name = "wasm-metadata"
version = "0.10.11" version = "0.10.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2167ce53b2faa16a92c6cafd4942cff16c9a4fa0c5a5a0a41131ee4e49fc055f" checksum = "d835d67708f6374937c550ad8dd1d17c616ae009e3f00d7a0ac9f7825e78c36a"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"indexmap", "indexmap",
@ -688,9 +689,9 @@ dependencies = [
[[package]] [[package]]
name = "wasmparser" name = "wasmparser"
version = "0.116.1" version = "0.118.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a58e28b80dd8340cb07b8242ae654756161f6fc8d0038123d679b7b99964fa50" checksum = "95ee9723b928e735d53000dec9eae7b07a60e490c85ab54abb66659fc61bfcd9"
dependencies = [ dependencies = [
"indexmap", "indexmap",
"semver", "semver",
@ -720,8 +721,8 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]] [[package]]
name = "wit-bindgen" name = "wit-bindgen"
version = "0.13.1" version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [ dependencies = [
"bitflags 2.4.1", "bitflags 2.4.1",
"wit-bindgen-rust-macro", "wit-bindgen-rust-macro",
@ -729,8 +730,8 @@ dependencies = [
[[package]] [[package]]
name = "wit-bindgen-core" name = "wit-bindgen-core"
version = "0.13.1" version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"wit-component", "wit-component",
@ -739,8 +740,8 @@ dependencies = [
[[package]] [[package]]
name = "wit-bindgen-rust" name = "wit-bindgen-rust"
version = "0.13.2" version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"heck", "heck",
@ -751,8 +752,8 @@ dependencies = [
[[package]] [[package]]
name = "wit-bindgen-rust-macro" name = "wit-bindgen-rust-macro"
version = "0.13.1" version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"proc-macro2", "proc-macro2",
@ -765,9 +766,9 @@ dependencies = [
[[package]] [[package]]
name = "wit-component" name = "wit-component"
version = "0.17.0" version = "0.18.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "480cc1a078b305c1b8510f7c455c76cbd008ee49935f3a6c5fd5e937d8d95b1e" checksum = "5b8a35a2a9992898c9d27f1664001860595a4bc99d32dd3599d547412e17d7e2"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bitflags 2.4.1", "bitflags 2.4.1",
@ -784,9 +785,9 @@ dependencies = [
[[package]] [[package]]
name = "wit-parser" name = "wit-parser"
version = "0.12.2" version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43771ee863a16ec4ecf9da0fc65c3bbd4a1235c8e3da5f094b562894843dfa76" checksum = "15df6b7b28ce94b8be39d8df5cb21a08a4f3b9f33b631aedb4aa5776f785ead3"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"id-arena", "id-arena",

View File

@ -1,10 +1,8 @@
[package] [package]
name = "chess" name = "chess"
version = "0.1.0" version = "0.2.0"
edition = "2021" edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[profile.release] [profile.release]
panic = "abort" panic = "abort"
opt-level = "s" opt-level = "s"
@ -15,10 +13,11 @@ anyhow = "1.0"
base64 = "0.13" base64 = "0.13"
bincode = "1.3.3" bincode = "1.3.3"
pleco = "0.5" pleco = "0.5"
serde = {version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" serde_json = "1.0"
uqbar_process_lib = { git = "ssh://git@github.com/uqbar-dao/process_lib.git", rev = "5e1b94a" } url = "*"
wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "5390bab780733f1660d14c254ec985df2816bf1d" } uqbar_process_lib = { git = "ssh://git@github.com/uqbar-dao/process_lib.git", rev = "c6dd31b" }
wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "efcc759" }
[lib] [lib]
crate-type = ["cdylib"] crate-type = ["cdylib"]

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -5,8 +5,11 @@
"on_panic": "Restart", "on_panic": "Restart",
"request_networking": true, "request_networking": true,
"request_messaging": [ "request_messaging": [
"net:sys:uqbar"
],
"grant_messaging": [
"http_server:sys:uqbar" "http_server:sys:uqbar"
], ],
"public": false "public": true
} }
] ]

View File

@ -1,39 +1,45 @@
#![feature(let_chains)] #![feature(let_chains)]
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
extern crate base64;
extern crate pleco;
use pleco::Board; use pleco::Board;
use uqbar_process_lib::uqbar::process::standard as wit; use serde::{Deserialize, Serialize};
use std::collections::{HashMap, HashSet};
use uqbar_process_lib::{ use uqbar_process_lib::{
get_payload, get_typed_state, grant_messaging, http, println, receive, set_state, Address, await_message, call_init, get_payload, get_typed_state, http, println, set_state, Address,
Message, Payload, ProcessId, Request, Response, Message, NodeId, Payload, Request, Response,
}; };
extern crate base64;
mod utils; // Lazy way to include our static files in the binary. We'll use these to serve
// our chess app's frontend.
const CHESS_HTML: &str = include_str!("../pkg/chess.html");
const CHESS_JS: &str = include_str!("../pkg/index.js");
const CHESS_CSS: &str = include_str!("../pkg/index.css");
wit_bindgen::generate!({ //
path: "../../wit", // Our "chess protocol" request/response format. We'll always serialize these
world: "process", // to a byte vector and send them over IPC.
exports: { //
world: Component,
},
});
struct Component; #[derive(Debug, Serialize, Deserialize)]
enum ChessRequest {
#[derive(Clone, Debug)] NewGame { white: String, black: String },
pub struct Game { Move { game_id: String, move_str: String },
pub id: String, // the node with whom we are playing Resign(String),
pub turns: u64,
pub board: Board,
pub white: String,
pub black: String,
pub ended: bool,
} }
#[derive(Debug, Eq, PartialEq, Serialize, Deserialize)]
enum ChessResponse {
NewGameAccepted,
NewGameRejected,
MoveAccepted,
MoveRejected,
}
//
// Our serializable state format.
//
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct StoredGame { struct Game {
pub id: String, // the node with whom we are playing pub id: String, // the node with whom we are playing
pub turns: u64, pub turns: u64,
pub board: String, pub board: String,
@ -42,280 +48,398 @@ pub struct StoredGame {
pub ended: bool, pub ended: bool,
} }
#[derive(Clone, Debug)] #[derive(Debug, Serialize, Deserialize)]
pub struct ChessState { struct ChessState {
pub games: HashMap<String, Game>, // game is by opposing player id pub games: HashMap<String, Game>, // game is by opposing player id
pub records: HashMap<String, (u64, u64, u64)>, // wins, losses, draws pub clients: HashSet<u32>, // doesn't get persisted
} }
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct StoredChessState { struct StoredChessState {
pub games: HashMap<String, StoredGame>, // game is by opposing player id pub games: HashMap<String, Game>, // game is by opposing player id
pub records: HashMap<String, (u64, u64, u64)>, // wins, losses, draws
} }
const CHESS_PAGE: &str = include_str!("../pkg/chess.html"); fn save_chess_state(state: &ChessState) {
const CHESS_JS: &str = include_str!("../pkg/index.js"); set_state(&bincode::serialize(&state.games).unwrap());
const CHESS_CSS: &str = include_str!("../pkg/index.css"); }
impl Guest for Component { fn load_chess_state() -> ChessState {
fn init(our: String) { match get_typed_state(|bytes| Ok(bincode::deserialize::<HashMap<String, Game>>(bytes)?)) {
let our = Address::from_str(&our).unwrap(); Some(games) => ChessState {
println!("{our}: start"); games,
clients: HashSet::new(),
},
None => ChessState {
games: HashMap::new(),
clients: HashSet::new(),
},
}
}
grant_messaging( fn send_ws_update(our: &Address, game: &Game, open_channels: &HashSet<u32>) -> anyhow::Result<()> {
&our, for channel in open_channels {
vec![ProcessId::new(Some("http_server"), "sys", "uqbar")], Request::new()
); .target((&our.node, "http_server", "sys", "uqbar"))
.ipc(serde_json::to_vec(
&http::HttpServerAction::WebSocketPush {
channel_id: *channel,
message_type: http::WsMessageType::Binary,
},
)?)
.payload(Payload {
mime: Some("application/json".to_string()),
bytes: serde_json::json!({
"kind": "game_update",
"data": game,
})
.to_string()
.into_bytes(),
})
.send()?;
}
Ok(())
}
// serve static page at / // Boilerplate: generate the wasm bindings for an Uqbar app
// dynamically handle requests to /games wit_bindgen::generate!({
http::bind_http_static_path( path: "../../wit",
"/", world: "process",
true, exports: {
false, world: Component,
Some("text/html".to_string()), },
CHESS_PAGE });
.replace("${node}", &our.node) // After generating bindings, use this macro to define the Component struct
.replace("${process}", &our.process.to_string()) // and its init() function, which the kernel will look for on startup.
// TODO serve these independently on paths.. call_init!(initialize);
// also build utils for just serving a vfs dir
.replace("${js}", CHESS_JS)
.replace("${css}", CHESS_CSS)
.as_bytes()
.to_vec(),
)
.unwrap();
http::bind_http_path("/games", true, false).unwrap();
let mut state: ChessState = match get_typed_state(|bytes| { fn initialize(our: Address) {
Ok(bincode::deserialize::<StoredChessState>(bytes)?) // A little printout to show in terminal that the process has started.
}) { println!("{} by {}: start", our.process(), our.publisher());
Some(mut state) => ChessState {
games: state
.games
.iter_mut()
.map(|(id, game)| {
(
id.clone(),
Game {
id: id.to_owned(),
turns: game.turns,
board: Board::from_fen(&game.board).unwrap_or(Board::start_pos()),
white: game.white.to_owned(),
black: game.black.to_owned(),
ended: game.ended,
},
)
})
.collect(),
records: state.records,
},
None => ChessState {
games: HashMap::new(),
records: HashMap::new(),
},
};
loop { // serve static page at /index.html, /index.js, /index.css
let Ok((source, message)) = receive() else { // dynamically handle requests to /games
println!("chess: got network error"); http::bind_http_static_path(
"/",
true, // only serve for ourselves
false, // can access remotely
Some("text/html".to_string()),
CHESS_HTML
.replace("${node}", &our.node)
.replace("${process}", &our.process.to_string())
.as_bytes()
.to_vec(),
)
.unwrap();
http::bind_http_static_path(
"/index.js",
true,
false,
Some("text/javascript".to_string()),
CHESS_JS.as_bytes().to_vec(),
)
.unwrap();
http::bind_http_static_path(
"/index.css",
true,
false,
Some("text/css".to_string()),
CHESS_CSS.as_bytes().to_vec(),
)
.unwrap();
http::bind_http_path("/games", true, false).unwrap();
// Grab our state, then enter the main event loop.
let mut state: ChessState = load_chess_state();
main_loop(&our, &mut state);
}
fn main_loop(our: &Address, state: &mut ChessState) {
loop {
// Call await_message() to wait for any incoming messages.
// If we get a network error, make a print and throw it away.
// In a high-quality consumer-grade app, we'd want to explicitly handle
// this and surface it to the user.
match await_message() {
Err(send_error) => {
println!("{our}: got network error: {send_error:?}");
continue; continue;
};
let Message::Request(request) = message else {
println!("chess: got unexpected Response");
continue;
};
match handle_request(&our, &source, &request, &mut state) {
Ok(()) => continue,
Err(e) => println!("chess: error handling request: {:?}", e),
} }
Ok(message) => match handle_request(&our, &message, state) {
Ok(()) => continue,
Err(e) => println!("{our}: error handling request: {:?}", e),
},
} }
} }
} }
fn handle_request( /// Handle chess protocol messages from ourself *or* other nodes.
our: &Address, fn handle_request(our: &Address, message: &Message, state: &mut ChessState) -> anyhow::Result<()> {
source: &Address, // Throw away responses. We never expect any responses *here*, because for every
request: &wit::Request, // chess protocol request, we *await* its response in-place. This is appropriate
state: &mut ChessState, // for direct node<>node comms, less appropriate for other circumstances...
) -> anyhow::Result<()> { if !message.is_request() {
if source.process == "chess:chess:uqbar" { return Err(anyhow::anyhow!("message was response"));
let message_json = serde_json::from_slice::<serde_json::Value>(&request.ipc)?; }
handle_chess_request(our, source, message_json, state) // If the request is from another node, handle it as an incoming request.
} else if source.process.to_string() == "http_server:sys:uqbar" { // Note that we can enforce the ProcessId as well, but it shouldn't be a trusted
let http_request = serde_json::from_slice::<http::IncomingHttpRequest>(&request.ipc)?; // piece of information, since another node can easily spoof any ProcessId on a request.
handle_http_request(our, http_request, state) // It can still be useful simply as a protocol-level switch to handle different kinds of
// requests from the same node, with the knowledge that the remote node can finagle with
// which ProcessId a given message can be from. It's their code, after all.
if message.source().node != our.node {
// Deserialize the request IPC to our format, and throw it away if it
// doesn't fit.
let Ok(chess_request) = serde_json::from_slice::<ChessRequest>(message.ipc()) else {
return Err(anyhow::anyhow!("invalid chess request"));
};
handle_chess_request(our, &message.source().node, state, &chess_request)
// ...and if the request is from ourselves, handle it as our own!
// Note that since this is a local request, we *can* trust the ProcessId.
// Here, we'll accept messages from the local terminal so as to make this a "CLI" app.
} else if message.source().node == our.node
&& message.source().process == "terminal:terminal:uqbar"
{
let Ok(chess_request) = serde_json::from_slice::<ChessRequest>(message.ipc()) else {
return Err(anyhow::anyhow!("invalid chess request"));
};
handle_local_request(our, state, &chess_request)
} else if message.source().node == our.node
&& message.source().process == "http_server:sys:uqbar"
{
// receive HTTP requests and websocket connection messages from our server
match serde_json::from_slice::<http::HttpServerRequest>(message.ipc())? {
http::HttpServerRequest::Http(ref incoming) => {
match handle_http_request(our, state, incoming) {
Ok(()) => Ok(()),
Err(e) => {
println!("chess: error handling http request: {:?}", e);
http::send_response(
http::StatusCode::SERVICE_UNAVAILABLE,
None,
"Service Unavailable".to_string().as_bytes().to_vec(),
)
}
}
}
http::HttpServerRequest::WebSocketOpen(channel_id) => {
// client frontend opened a websocket
state.clients.insert(channel_id);
Ok(())
}
http::HttpServerRequest::WebSocketClose(channel_id) => {
// client frontend closed a websocket
state.clients.remove(&channel_id);
Ok(())
}
http::HttpServerRequest::WebSocketPush { .. } => {
// client frontend sent a websocket message
// we don't expect this! we only use websockets to push updates
Ok(())
}
}
} else { } else {
return Err(anyhow::anyhow!("chess: got request from unexpected source")); // If we get a request from ourselves that isn't from the terminal, we'll just
// throw it away. This is a good place to put a printout to show that we've
// received a request from ourselves that we don't know how to handle.
return Err(anyhow::anyhow!(
"got request from not-the-terminal, ignoring"
));
} }
} }
/// Handle chess protocol messages from other nodes.
fn handle_chess_request( fn handle_chess_request(
our: &Address, our: &Address,
source: &Address, source_node: &NodeId,
message_json: serde_json::Value,
state: &mut ChessState, state: &mut ChessState,
action: &ChessRequest,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
let action = message_json["action"].as_str().unwrap_or(""); println!("chess: handling action from {source_node}: {action:?}");
let game_id = &source.node;
// For simplicity's sake, we'll just use the node we're playing with as the game id.
// This limits us to one active game per partner.
let game_id = source_node;
match action { match action {
"new_game" => { ChessRequest::NewGame { white, black } => {
// make a new game with source.node if the current game has ended // Make a new game with source.node
if let Some(game) = state.games.get(game_id) { // This will replace any existing game with source.node!
if !game.ended { if state.games.contains_key(game_id) {
return Response::new() println!("chess: resetting game with {game_id} on their request!");
.ipc(vec![])
.payload(Payload {
mime: Some("application/octet-stream".to_string()),
bytes: "conflict".as_bytes().to_vec(),
})
.send();
}
} }
let game = Game { let game = Game {
id: game_id.to_string(), id: game_id.to_string(),
turns: 0, turns: 0,
board: Board::start_pos(), board: Board::start_pos().fen(),
white: message_json["white"] white: white.to_string(),
.as_str() black: black.to_string(),
.unwrap_or(game_id)
.to_string(),
black: message_json["black"]
.as_str()
.unwrap_or(&our.node)
.to_string(),
ended: false, ended: false,
}; };
state.games.insert(game_id.to_string(), game.clone()); // Use our helper function to persist state after every action.
// The simplest and most trivial way to keep state. You'll want to
utils::send_ws_update(&our, &game)?; // use a database or something in a real app, and consider performance
utils::save_chess_state(&state); // when doing intensive data-based operations.
send_ws_update(&our, &game, &state.clients)?;
state.games.insert(game_id.to_string(), game);
save_chess_state(&state);
// Send a response to tell them we've accepted the game.
// Remember, the other player is waiting for this.
Response::new() Response::new()
.ipc(vec![]) .ipc(serde_json::to_vec(&ChessResponse::NewGameAccepted)?)
.payload(Payload {
mime: Some("application/octet-stream".to_string()),
bytes: "success".as_bytes().to_vec(),
})
.send() .send()
} }
"make_move" => { ChessRequest::Move { ref move_str, .. } => {
// check the move and then update if correct and send WS update // Get the associated game, and respond with an error if
// we don't have it in our state.
let Some(game) = state.games.get_mut(game_id) else { let Some(game) = state.games.get_mut(game_id) else {
// If we don't have a game with them, reject the move.
return Response::new() return Response::new()
.ipc(vec![]) .ipc(serde_json::to_vec(&ChessResponse::MoveRejected)?)
.payload(Payload { .send()
mime: Some("application/octet-stream".to_string()),
bytes: "not found".as_bytes().to_vec(),
})
.send();
}; };
let valid_move = game // Convert the saved board to one we can manipulate.
.board let mut board = Board::from_fen(&game.board).unwrap();
.apply_uci_move(message_json["move"].as_str().unwrap_or("")); if !board.apply_uci_move(move_str) {
if valid_move { // Reject invalid moves!
game.turns += 1; return Response::new()
let checkmate = game.board.checkmate(); .ipc(serde_json::to_vec(&ChessResponse::MoveRejected)?)
let draw = game.board.stalemate(); .send();
}
if checkmate || draw { game.turns += 1;
if board.checkmate() || board.stalemate() {
game.ended = true;
}
// Persist state.
game.board = board.fen();
send_ws_update(&our, &game, &state.clients)?;
save_chess_state(&state);
// Send a response to tell them we've accepted the move.
Response::new()
.ipc(serde_json::to_vec(&ChessResponse::MoveAccepted)?)
.send()
}
ChessRequest::Resign(_) => {
// They've resigned. The sender isn't waiting for a response to this,
// so we don't need to send one.
match state.games.get_mut(game_id) {
Some(game) => {
game.ended = true; game.ended = true;
let winner = if checkmate { send_ws_update(&our, &game, &state.clients)?;
if game.turns % 2 == 1 { save_chess_state(&state);
game.white.clone()
} else {
game.black.clone()
}
} else {
"".to_string()
};
// update the records
if draw {
if let Some(record) = state.records.get_mut(&game.id) {
record.2 += 1;
} else {
state.records.insert(game.id.clone(), (0, 0, 1));
}
} else {
if let Some(record) = state.records.get_mut(&game.id) {
if winner == our.node {
record.0 += 1;
} else {
record.1 += 1;
}
} else {
if winner == our.node {
state.records.insert(game.id.clone(), (1, 0, 0));
} else {
state.records.insert(game.id.clone(), (0, 1, 0));
}
}
}
} }
None => {}
utils::send_ws_update(&our, &game)?;
utils::save_chess_state(&state);
Response::new()
.ipc(vec![])
.payload(Payload {
mime: Some("application/octet-stream".to_string()),
bytes: "success".as_bytes().to_vec(),
})
.send()
} else {
Response::new()
.ipc(vec![])
.payload(Payload {
mime: Some("application/octet-stream".to_string()),
bytes: "invalid move".as_bytes().to_vec(),
})
.send()
} }
Ok(())
} }
"end_game" => {
// end the game and send WS update, update the standings
let Some(game) = state.games.get_mut(game_id) else {
return Response::new()
.ipc(vec![])
.payload(Payload {
mime: Some("application/octet-stream".to_string()),
bytes: "not found".as_bytes().to_vec(),
})
.send();
};
game.ended = true;
if let Some(record) = state.records.get_mut(&game.id) {
record.0 += 1;
} else {
state.records.insert(game.id.clone(), (1, 0, 0));
}
utils::send_ws_update(&our, &game)?;
utils::save_chess_state(&state);
Response::new()
.ipc(vec![])
.payload(Payload {
mime: Some("application/octet-stream".to_string()),
bytes: "success".as_bytes().to_vec(),
})
.send()
}
_ => return Err(anyhow::anyhow!("chess: got unexpected action")),
} }
} }
/// Handle actions we are performing. Here's where we'll send_and_await various requests.
fn handle_local_request(
our: &Address,
state: &mut ChessState,
action: &ChessRequest,
) -> anyhow::Result<()> {
match action {
ChessRequest::NewGame { white, black } => {
// Create a new game. We'll enforce that one of the two players is us.
if white != &our.node && black != &our.node {
return Err(anyhow::anyhow!("cannot start a game without us!"));
}
let game_id = if white == &our.node { black } else { white };
// If we already have a game with this player, throw an error.
if let Some(game) = state.games.get(game_id)
&& !game.ended
{
return Err(anyhow::anyhow!("already have a game with {game_id}"));
};
// Send the other player a NewGame request
// The request is exactly the same as what we got from terminal.
// We'll give them 5 seconds to respond...
let Ok(Message::Response { ref ipc, .. }) = Request::new()
.target((game_id.as_ref(), our.process.clone()))
.ipc(serde_json::to_vec(&action)?)
.send_and_await_response(5)? else {
return Err(anyhow::anyhow!("other player did not respond properly to new game request"))
};
// If they accept, create a new game -- otherwise, error out.
if serde_json::from_slice::<ChessResponse>(ipc)? != ChessResponse::NewGameAccepted {
return Err(anyhow::anyhow!("other player rejected new game request!"));
}
// New game with default board.
let game = Game {
id: game_id.to_string(),
turns: 0,
board: Board::start_pos().fen(),
white: white.to_string(),
black: black.to_string(),
ended: false,
};
state.games.insert(game_id.to_string(), game);
save_chess_state(&state);
Ok(())
}
ChessRequest::Move { game_id, move_str } => {
// Make a move. We'll enforce that it's our turn. The game_id is the
// person we're playing with.
let Some(game) = state.games.get_mut(game_id) else {
return Err(anyhow::anyhow!("no game with {game_id}"));
};
if (game.turns % 2 == 0 && game.white != our.node)
|| (game.turns % 2 == 1 && game.black != our.node)
{
return Err(anyhow::anyhow!("not our turn!"));
} else if game.ended {
return Err(anyhow::anyhow!("that game is over!"));
}
let mut board = Board::from_fen(&game.board).unwrap();
if !board.apply_uci_move(move_str) {
return Err(anyhow::anyhow!("illegal move!"));
}
// Send the move to the other player, then check if the game is over.
// The request is exactly the same as what we got from terminal.
// We'll give them 5 seconds to respond...
let Ok(Message::Response { ref ipc, .. }) = Request::new()
.target((game_id.as_ref(), our.process.clone()))
.ipc(serde_json::to_vec(&action)?)
.send_and_await_response(5)? else {
return Err(anyhow::anyhow!("other player did not respond properly to our move"))
};
if serde_json::from_slice::<ChessResponse>(ipc)? != ChessResponse::MoveAccepted {
return Err(anyhow::anyhow!("other player rejected our move"));
}
game.turns += 1;
if board.checkmate() || board.stalemate() {
game.ended = true;
}
game.board = board.fen();
save_chess_state(&state);
Ok(())
}
ChessRequest::Resign(ref with_who) => {
// Resign from a game with a given player.
let Some(game) = state.games.get_mut(with_who) else {
return Err(anyhow::anyhow!("no game with {with_who}"));
};
// send the other player an end game request -- no response expected
Request::new()
.target((with_who.as_ref(), our.process.clone()))
.ipc(serde_json::to_vec(&action)?)
.send()?;
game.ended = true;
save_chess_state(&state);
Ok(())
}
}
}
/// Handle HTTP requests from our own frontend.
fn handle_http_request( fn handle_http_request(
our: &Address, our: &Address,
http_request: http::IncomingHttpRequest,
state: &mut ChessState, state: &mut ChessState,
http_request: &http::IncomingHttpRequest,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
if http_request.path()? != "/games" { if http_request.path()? != "games" {
return http::send_response( return http::send_response(
http::StatusCode::NOT_FOUND, http::StatusCode::NOT_FOUND,
None, None,
@ -323,20 +447,17 @@ fn handle_http_request(
); );
} }
match http_request.method.as_str() { match http_request.method.as_str() {
// on GET: give the frontend all of our active games
"GET" => http::send_response( "GET" => http::send_response(
http::StatusCode::OK, http::StatusCode::OK,
Some(HashMap::from([( Some(HashMap::from([(
String::from("Content-Type"), String::from("Content-Type"),
String::from("application/json"), String::from("application/json"),
)])), )])),
serde_json::to_vec(&serde_json::json!(state serde_json::to_vec(&state.games)?,
.games
.iter()
.map(|(id, game)| (id.to_string(), utils::json_game(game)))
.collect::<HashMap<String, serde_json::Value>>()))?,
), ),
// on POST: create a new game
"POST" => { "POST" => {
// create a new game
let Some(payload) = get_payload() else { let Some(payload) = get_payload() else {
return http::send_response(http::StatusCode::BAD_REQUEST, None, vec![]); return http::send_response(http::StatusCode::BAD_REQUEST, None, vec![]);
}; };
@ -360,38 +481,33 @@ fn handle_http_request(
.to_string(); .to_string();
// send the other player a new game request // send the other player a new game request
let response = Request::new() let Ok(msg) = Request::new()
.target((game_id, "chess", "chess", "uqbar")) .target((game_id, our.process.clone()))
.ipc(serde_json::to_vec(&serde_json::json!({ .ipc(serde_json::to_vec(&ChessRequest::NewGame {
"action": "new_game", white: player_white.clone(),
"white": player_white.clone(), black: player_black.clone(),
"black": player_black.clone(), })?)
}))?) .send_and_await_response(5)? else {
.send_and_await_response(30)?; return Err(anyhow::anyhow!("other player did not respond properly to new game request"))
};
// if they accept, create a new game // if they accept, create a new game
// otherwise, should surface error to FE... // otherwise, should surface error to FE...
let Ok((_source, Message::Response((resp, _context)))) = response else { if serde_json::from_slice::<ChessResponse>(msg.ipc())? != ChessResponse::NewGameAccepted
return http::send_response( {
http::StatusCode::SERVICE_UNAVAILABLE, return Err(anyhow::anyhow!("other player rejected new game request"));
None,
"Service Unavailable".to_string().as_bytes().to_vec(),
);
};
if resp.ipc != "success".as_bytes() {
return http::send_response(http::StatusCode::SERVICE_UNAVAILABLE, None, vec![]);
} }
// create a new game // create a new game
let game = Game { let game = Game {
id: game_id.to_string(), id: game_id.to_string(),
turns: 0, turns: 0,
board: Board::start_pos(), board: Board::start_pos().fen(),
white: player_white, white: player_white,
black: player_black, black: player_black,
ended: false, ended: false,
}; };
let body = serde_json::to_vec(&utils::json_game(&game))?; let body = serde_json::to_vec(&game)?;
state.games.insert(game_id.to_string(), game); state.games.insert(game_id.to_string(), game);
utils::save_chess_state(&state); save_chess_state(&state);
http::send_response( http::send_response(
http::StatusCode::OK, http::StatusCode::OK,
Some(HashMap::from([( Some(HashMap::from([(
@ -401,8 +517,8 @@ fn handle_http_request(
body, body,
) )
} }
// on PUT: make a move
"PUT" => { "PUT" => {
// make a move
let Some(payload) = get_payload() else { let Some(payload) = get_payload() else {
return http::send_response(http::StatusCode::BAD_REQUEST, None, vec![]); return http::send_response(http::StatusCode::BAD_REQUEST, None, vec![]);
}; };
@ -420,71 +536,38 @@ fn handle_http_request(
} else if game.ended { } else if game.ended {
return http::send_response(http::StatusCode::CONFLICT, None, vec![]); return http::send_response(http::StatusCode::CONFLICT, None, vec![]);
} }
let move_str = payload_json["move"].as_str().unwrap_or(""); let Some(move_str) = payload_json["move"].as_str() else {
if !game.board.apply_uci_move(move_str) { return http::send_response(http::StatusCode::BAD_REQUEST, None, vec![]);
};
let mut board = Board::from_fen(&game.board).unwrap();
if !board.apply_uci_move(move_str) {
// TODO surface illegal move to player or something here // TODO surface illegal move to player or something here
return http::send_response(http::StatusCode::BAD_REQUEST, None, vec![]); return http::send_response(http::StatusCode::BAD_REQUEST, None, vec![]);
} }
// send the move to the other player // send the move to the other player
// check if the game is over // check if the game is over
// if so, update the records // if so, update the records
let response = Request::new() let Ok(msg) = Request::new()
.target((game_id, "chess", "chess", "uqbar")) .target((game_id, our.process.clone()))
.ipc(serde_json::to_vec(&serde_json::json!({ .ipc(serde_json::to_vec(&ChessRequest::Move {
"action": "make_move", game_id: game_id.to_string(),
"move": move_str, move_str: move_str.to_string(),
}))?) })?)
.send_and_await_response(30)?; .send_and_await_response(5)? else {
let Ok((_source, Message::Response((resp, _context)))) = response else { return Err(anyhow::anyhow!("other player did not respond properly to our move"))
// TODO surface error to player, let them know other player is };
// offline or whatever they respond here was invalid if serde_json::from_slice::<ChessResponse>(msg.ipc())? != ChessResponse::MoveAccepted {
return http::send_response(http::StatusCode::BAD_REQUEST, None, vec![]); return Err(anyhow::anyhow!("other player rejected our move"));
};
if resp.ipc != "success".as_bytes() {
return http::send_response(http::StatusCode::SERVICE_UNAVAILABLE, None, vec![]);
} }
// update the game // update the game
game.turns += 1; game.turns += 1;
let checkmate = game.board.checkmate(); if board.checkmate() || board.stalemate() {
let draw = game.board.stalemate();
if checkmate || draw {
game.ended = true; game.ended = true;
let winner = if checkmate {
if game.turns % 2 == 1 {
&game.white
} else {
&game.black
}
} else {
""
};
// update the records
if draw {
if let Some(record) = state.records.get_mut(&game.id) {
record.2 += 1;
} else {
state.records.insert(game.id.clone(), (0, 0, 1));
}
} else {
if let Some(record) = state.records.get_mut(&game.id) {
if winner == our.node {
record.0 += 1;
} else {
record.1 += 1;
}
} else {
if winner == our.node {
state.records.insert(game.id.clone(), (1, 0, 0));
} else {
state.records.insert(game.id.clone(), (0, 1, 0));
}
}
}
} }
// game is not over, update state and return to FE game.board = board.fen();
let body = serde_json::to_vec(&utils::json_game(&game))?; // update state and return to FE
utils::save_chess_state(&state); let body = serde_json::to_vec(&game)?;
save_chess_state(&state);
// return the game // return the game
http::send_response( http::send_response(
http::StatusCode::OK, http::StatusCode::OK,
@ -495,41 +578,22 @@ fn handle_http_request(
body, body,
) )
} }
// on DELETE: end the game
"DELETE" => { "DELETE" => {
// "end the game"? let Some(game_id) = http_request.query_params.get("id") else {
let query_params = http_request.query_params()?;
let Some(game_id) = query_params.get("id") else {
return http::send_response(http::StatusCode::BAD_REQUEST, None, vec![]); return http::send_response(http::StatusCode::BAD_REQUEST, None, vec![]);
}; };
let Some(game) = state.games.get_mut(game_id) else { let Some(game) = state.games.get_mut(game_id) else {
return http::send_response(http::StatusCode::BAD_REQUEST, None, vec![]); return http::send_response(http::StatusCode::BAD_REQUEST, None, vec![]);
}; };
// send the other player an end game request // send the other player an end game request
let response = Request::new() Request::new()
.target((game_id, "chess", "chess", "uqbar")) .target((game_id.as_str(), our.process.clone()))
.ipc(serde_json::to_vec(&serde_json::json!({ .ipc(serde_json::to_vec(&ChessRequest::Resign(our.node.clone()))?)
"action": "end_game", .send()?;
}))?)
.send_and_await_response(30)?;
let Ok((_source, Message::Response((resp, _context)))) = response else {
// TODO surface error to player, let them know other player is
// offline or whatever they respond here was invalid
return http::send_response(http::StatusCode::SERVICE_UNAVAILABLE, None, vec![]);
};
if resp.ipc != "success".as_bytes() {
return http::send_response(http::StatusCode::SERVICE_UNAVAILABLE, None, vec![]);
}
game.ended = true; game.ended = true;
if let Some(record) = state.records.get_mut(&game.id) { let body = serde_json::to_vec(&game)?;
record.1 += 1; save_chess_state(&state);
} else {
state.records.insert(game.id.clone(), (0, 1, 0));
}
// return the game
let body = serde_json::to_vec(&utils::json_game(&game))?;
utils::save_chess_state(&state);
http::send_response( http::send_response(
http::StatusCode::OK, http::StatusCode::OK,
Some(HashMap::from([( Some(HashMap::from([(
@ -539,11 +603,7 @@ fn handle_http_request(
body, body,
) )
} }
_ => Response::new() // Any other method will be rejected.
.ipc(serde_json::to_vec(&http::HttpResponse { _ => http::send_response(http::StatusCode::METHOD_NOT_ALLOWED, None, vec![]),
status: 405,
headers: HashMap::new(),
})?)
.send(),
} }
} }

View File

@ -1,82 +0,0 @@
use crate::*;
pub fn save_chess_state(state: &ChessState) {
let stored_state = convert_state(&state);
set_state(&bincode::serialize(&stored_state).unwrap());
}
fn convert_game(game: Game) -> StoredGame {
StoredGame {
id: game.id,
turns: game.turns,
board: game.board.fen(),
white: game.white,
black: game.black,
ended: game.ended,
}
}
fn convert_state(state: &ChessState) -> StoredChessState {
StoredChessState {
games: state
.games
.iter()
.map(|(id, game)| (id.to_string(), convert_game(game.clone())))
.collect(),
records: state.records.clone(),
}
}
pub fn json_game(game: &Game) -> serde_json::Value {
serde_json::json!({
"id": game.id,
"turns": game.turns,
"board": game.board.fen(),
"white": game.white,
"black": game.black,
"ended": game.ended,
})
}
pub fn send_ws_update(our: &Address, game: &Game) -> anyhow::Result<()> {
Request::new()
.target((&our.node, "http_server", "sys", "uqbar"))
.ipc(
serde_json::json!({
"EncryptAndForward": {
"channel_id": our.process.to_string(),
"forward_to": {
"node": our.node.clone(),
"process": {
"process_name": "http_server",
"package_name": "sys",
"publisher_node": "uqbar"
}
}, // node, process
"json": Some(serde_json::json!({ // this is the JSON to forward
"WebSocketPush": {
"target": {
"node": our.node.clone(),
"id": "chess", // If the message passed in an ID then we could send to just that ID
}
}
})),
}
})
.to_string()
.as_bytes()
.to_vec(),
)
.payload(Payload {
mime: Some("application/json".to_string()),
bytes: serde_json::json!({
"kind": "game_update",
"data": json_game(game),
})
.to_string()
.as_bytes()
.to_vec(),
})
.send()
}

View File

@ -58,9 +58,9 @@ dependencies = [
[[package]] [[package]]
name = "getrandom" name = "getrandom"
version = "0.2.10" version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
@ -69,9 +69,9 @@ dependencies = [
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.14.2" version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
[[package]] [[package]]
name = "heck" name = "heck"
@ -134,9 +134,9 @@ dependencies = [
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "1.0.9" version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
[[package]] [[package]]
name = "leb128" name = "leb128"
@ -146,9 +146,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.150" version = "0.2.151"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4"
[[package]] [[package]]
name = "log" name = "log"
@ -170,9 +170,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.69" version = "1.0.70"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
@ -218,9 +218,9 @@ dependencies = [
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.15" version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
[[package]] [[package]]
name = "semver" name = "semver"
@ -230,18 +230,18 @@ checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.191" version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a834c4821019838224821468552240d4d95d14e751986442c816572d39a080c9" checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.191" version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46fa52d5646bce91b680189fe5b1c049d2ea38dabb4e2e7c8d00ca12cfbfbcfd" checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -261,9 +261,9 @@ dependencies = [
[[package]] [[package]]
name = "smallvec" name = "smallvec"
version = "1.11.1" version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
[[package]] [[package]]
name = "spdx" name = "spdx"
@ -276,9 +276,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.39" version = "2.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" checksum = "13fa70a4ee923979ffb522cacce59d34421ebdea5625e1073c4326ef9d2dd42e"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -322,9 +322,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]] [[package]]
name = "unicode-bidi" name = "unicode-bidi"
version = "0.3.13" version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416"
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
@ -355,8 +355,8 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
[[package]] [[package]]
name = "uqbar_process_lib" name = "uqbar_process_lib"
version = "0.3.0" version = "0.4.0"
source = "git+ssh://git@github.com/uqbar-dao/process_lib.git?rev=5e1b94a#5e1b94ae2f85c66da33ec52117a72b90d53c4d22" source = "git+ssh://git@github.com/uqbar-dao/process_lib.git?rev=3ea3a23#3ea3a23de46cda8ebe1ea8f3b9f764b57e7feada"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bincode", "bincode",
@ -388,18 +388,18 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]] [[package]]
name = "wasm-encoder" name = "wasm-encoder"
version = "0.36.2" version = "0.38.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "822b645bf4f2446b949776ffca47e2af60b167209ffb70814ef8779d299cd421" checksum = "0ad2b51884de9c7f4fe2fd1043fccb8dcad4b1e29558146ee57a144d15779f3f"
dependencies = [ dependencies = [
"leb128", "leb128",
] ]
[[package]] [[package]]
name = "wasm-metadata" name = "wasm-metadata"
version = "0.10.11" version = "0.10.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2167ce53b2faa16a92c6cafd4942cff16c9a4fa0c5a5a0a41131ee4e49fc055f" checksum = "d835d67708f6374937c550ad8dd1d17c616ae009e3f00d7a0ac9f7825e78c36a"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"indexmap", "indexmap",
@ -413,9 +413,9 @@ dependencies = [
[[package]] [[package]]
name = "wasmparser" name = "wasmparser"
version = "0.116.1" version = "0.118.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a58e28b80dd8340cb07b8242ae654756161f6fc8d0038123d679b7b99964fa50" checksum = "95ee9723b928e735d53000dec9eae7b07a60e490c85ab54abb66659fc61bfcd9"
dependencies = [ dependencies = [
"indexmap", "indexmap",
"semver", "semver",
@ -423,8 +423,8 @@ dependencies = [
[[package]] [[package]]
name = "wit-bindgen" name = "wit-bindgen"
version = "0.13.1" version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"wit-bindgen-rust-macro", "wit-bindgen-rust-macro",
@ -432,8 +432,8 @@ dependencies = [
[[package]] [[package]]
name = "wit-bindgen-core" name = "wit-bindgen-core"
version = "0.13.1" version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"wit-component", "wit-component",
@ -442,8 +442,8 @@ dependencies = [
[[package]] [[package]]
name = "wit-bindgen-rust" name = "wit-bindgen-rust"
version = "0.13.2" version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"heck", "heck",
@ -454,8 +454,8 @@ dependencies = [
[[package]] [[package]]
name = "wit-bindgen-rust-macro" name = "wit-bindgen-rust-macro"
version = "0.13.1" version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"proc-macro2", "proc-macro2",
@ -468,9 +468,9 @@ dependencies = [
[[package]] [[package]]
name = "wit-component" name = "wit-component"
version = "0.17.0" version = "0.18.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "480cc1a078b305c1b8510f7c455c76cbd008ee49935f3a6c5fd5e937d8d95b1e" checksum = "5b8a35a2a9992898c9d27f1664001860595a4bc99d32dd3599d547412e17d7e2"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bitflags", "bitflags",
@ -487,9 +487,9 @@ dependencies = [
[[package]] [[package]]
name = "wit-parser" name = "wit-parser"
version = "0.12.2" version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43771ee863a16ec4ecf9da0fc65c3bbd4a1235c8e3da5f094b562894843dfa76" checksum = "15df6b7b28ce94b8be39d8df5cb21a08a4f3b9f33b631aedb4aa5776f785ead3"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"id-arena", "id-arena",

View File

@ -13,10 +13,10 @@ lto = true
[dependencies] [dependencies]
anyhow = "1.0" anyhow = "1.0"
bincode = "1.3.3" bincode = "1.3.3"
serde = {version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" serde_json = "1.0"
uqbar_process_lib = { git = "ssh://git@github.com/uqbar-dao/process_lib.git", rev = "5e1b94a" } uqbar_process_lib = { git = "ssh://git@github.com/uqbar-dao/process_lib.git", rev = "3ea3a23" }
wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "5390bab780733f1660d14c254ec985df2816bf1d" } wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "efcc759" }
[lib] [lib]
crate-type = ["cdylib"] crate-type = ["cdylib"]

View File

@ -196,7 +196,7 @@
<h4>Apps:</h4> <h4>Apps:</h4>
<!-- <a id="file-transfer" href="/file-transfer">File Transfer</a> --> <!-- <a id="file-transfer" href="/file-transfer">File Transfer</a> -->
<a id="chess" href="/chess:chess:uqbar/">Chess [NOT WORKING]</a> <a id="chess" href="/chess:chess:uqbar/">Chess</a>
</div> </div>
<script>window.ourName = window.our = '${our}'</script> <script>window.ourName = window.our = '${our}'</script>
<script> <script>

View File

@ -1,7 +1,7 @@
#![feature(let_chains)] #![feature(let_chains)]
use uqbar_process_lib::{ use uqbar_process_lib::{
grant_messaging, http::bind_http_static_path, http::HttpServerError, println, receive, Address, await_message, grant_messaging, http::bind_http_static_path, http::HttpServerError, println, Address,
Message, ProcessId, Response, Message, ProcessId,
}; };
wit_bindgen::generate!({ wit_bindgen::generate!({
@ -44,20 +44,21 @@ fn main(our: Address) -> anyhow::Result<()> {
)?; )?;
loop { loop {
let Ok((ref source, ref message)) = receive() else { let Ok(ref message) = await_message() else {
println!("homepage: got network error??"); println!("homepage: got network error??");
continue; continue;
}; };
if let Message::Response((ref msg, _)) = message if let Message::Response { source, ipc, ..} = message
&& source.process == "http_server:sys:uqbar" && source.process == "http_server:sys:uqbar"
{ {
match serde_json::from_slice::<Result<(), HttpServerError>>(&msg.ipc) { match serde_json::from_slice::<Result<(), HttpServerError>>(&ipc) {
Ok(Ok(())) => continue, Ok(Ok(())) => continue,
Ok(Err(e)) => println!("homepage: got error from http_server: {e}"), Ok(Err(e)) => println!("homepage: got error from http_server: {e}"),
Err(_e) => println!("homepage: got malformed message from http_server!"), Err(_e) => println!("homepage: got malformed message from http_server!"),
} }
} else { } else {
println!("homepage: got message from {source:?}: {message:?}"); println!("homepage: got message: {message:?}");
//println!("homepage: got message from {source:?}: {message:?}");
} }
} }
} }

View File

@ -42,7 +42,7 @@ dependencies = [
"heck", "heck",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.39", "syn 2.0.40",
"syn-solidity", "syn-solidity",
"tiny-keccak", "tiny-keccak",
] ]
@ -192,12 +192,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]] [[package]]
name = "errno" name = "errno"
version = "0.3.5" version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
dependencies = [ dependencies = [
"libc", "libc",
"windows-sys", "windows-sys 0.52.0",
] ]
[[package]] [[package]]
@ -223,9 +223,9 @@ dependencies = [
[[package]] [[package]]
name = "getrandom" name = "getrandom"
version = "0.2.10" version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
@ -234,9 +234,9 @@ dependencies = [
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.14.2" version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
[[package]] [[package]]
name = "heck" name = "heck"
@ -299,9 +299,9 @@ dependencies = [
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "1.0.9" version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
@ -317,9 +317,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.150" version = "0.2.151"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4"
[[package]] [[package]]
name = "libm" name = "libm"
@ -329,9 +329,9 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
[[package]] [[package]]
name = "linux-raw-sys" name = "linux-raw-sys"
version = "0.4.10" version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456"
[[package]] [[package]]
name = "log" name = "log"
@ -369,18 +369,18 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.69" version = "1.0.70"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]] [[package]]
name = "proptest" name = "proptest"
version = "1.3.1" version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c003ac8c77cb07bb74f5f198bce836a689bcd5a42574612bf14d17bfd08c20e" checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf"
dependencies = [ dependencies = [
"bit-set", "bit-set",
"bit-vec", "bit-vec",
@ -477,9 +477,9 @@ dependencies = [
[[package]] [[package]]
name = "regex-syntax" name = "regex-syntax"
version = "0.7.5" version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
[[package]] [[package]]
name = "rmp" name = "rmp"
@ -505,9 +505,9 @@ dependencies = [
[[package]] [[package]]
name = "ruint" name = "ruint"
version = "1.11.0" version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "724fd11728a3804e9944b14cab63825024c40bf42f8af87c8b5d97c4bbacf426" checksum = "608a5726529f2f0ef81b8fde9873c4bb829d6b5b5ca6be4d97345ddf0749c825"
dependencies = [ dependencies = [
"proptest", "proptest",
"rand", "rand",
@ -534,15 +534,15 @@ dependencies = [
[[package]] [[package]]
name = "rustix" name = "rustix"
version = "0.38.21" version = "0.38.28"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316"
dependencies = [ dependencies = [
"bitflags 2.4.1", "bitflags 2.4.1",
"errno", "errno",
"libc", "libc",
"linux-raw-sys", "linux-raw-sys",
"windows-sys", "windows-sys 0.52.0",
] ]
[[package]] [[package]]
@ -559,9 +559,9 @@ dependencies = [
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.15" version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
[[package]] [[package]]
name = "semver" name = "semver"
@ -571,22 +571,22 @@ checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.192" version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001" checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.192" version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.39", "syn 2.0.40",
] ]
[[package]] [[package]]
@ -602,9 +602,9 @@ dependencies = [
[[package]] [[package]]
name = "smallvec" name = "smallvec"
version = "1.11.1" version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
[[package]] [[package]]
name = "smol_str" name = "smol_str"
@ -637,9 +637,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.39" version = "2.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" checksum = "13fa70a4ee923979ffb522cacce59d34421ebdea5625e1073c4326ef9d2dd42e"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -655,7 +655,7 @@ dependencies = [
"paste", "paste",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.39", "syn 2.0.40",
] ]
[[package]] [[package]]
@ -668,7 +668,7 @@ dependencies = [
"fastrand", "fastrand",
"redox_syscall", "redox_syscall",
"rustix", "rustix",
"windows-sys", "windows-sys 0.48.0",
] ]
[[package]] [[package]]
@ -688,7 +688,7 @@ checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.39", "syn 2.0.40",
] ]
[[package]] [[package]]
@ -723,9 +723,9 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94"
[[package]] [[package]]
name = "unicode-bidi" name = "unicode-bidi"
version = "0.3.13" version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416"
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
@ -756,8 +756,8 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
[[package]] [[package]]
name = "uqbar_process_lib" name = "uqbar_process_lib"
version = "0.3.0" version = "0.4.0"
source = "git+ssh://git@github.com/uqbar-dao/process_lib.git?rev=5e1b94a#5e1b94ae2f85c66da33ec52117a72b90d53c4d22" source = "git+ssh://git@github.com/uqbar-dao/process_lib.git?rev=3ea3a23#3ea3a23de46cda8ebe1ea8f3b9f764b57e7feada"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bincode", "bincode",
@ -804,18 +804,18 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]] [[package]]
name = "wasm-encoder" name = "wasm-encoder"
version = "0.36.2" version = "0.38.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "822b645bf4f2446b949776ffca47e2af60b167209ffb70814ef8779d299cd421" checksum = "0ad2b51884de9c7f4fe2fd1043fccb8dcad4b1e29558146ee57a144d15779f3f"
dependencies = [ dependencies = [
"leb128", "leb128",
] ]
[[package]] [[package]]
name = "wasm-metadata" name = "wasm-metadata"
version = "0.10.11" version = "0.10.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2167ce53b2faa16a92c6cafd4942cff16c9a4fa0c5a5a0a41131ee4e49fc055f" checksum = "d835d67708f6374937c550ad8dd1d17c616ae009e3f00d7a0ac9f7825e78c36a"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"indexmap", "indexmap",
@ -829,9 +829,9 @@ dependencies = [
[[package]] [[package]]
name = "wasmparser" name = "wasmparser"
version = "0.116.1" version = "0.118.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a58e28b80dd8340cb07b8242ae654756161f6fc8d0038123d679b7b99964fa50" checksum = "95ee9723b928e735d53000dec9eae7b07a60e490c85ab54abb66659fc61bfcd9"
dependencies = [ dependencies = [
"indexmap", "indexmap",
"semver", "semver",
@ -843,7 +843,16 @@ version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [ dependencies = [
"windows-targets", "windows-targets 0.48.5",
]
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets 0.52.0",
] ]
[[package]] [[package]]
@ -852,13 +861,28 @@ version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [ dependencies = [
"windows_aarch64_gnullvm", "windows_aarch64_gnullvm 0.48.5",
"windows_aarch64_msvc", "windows_aarch64_msvc 0.48.5",
"windows_i686_gnu", "windows_i686_gnu 0.48.5",
"windows_i686_msvc", "windows_i686_msvc 0.48.5",
"windows_x86_64_gnu", "windows_x86_64_gnu 0.48.5",
"windows_x86_64_gnullvm", "windows_x86_64_gnullvm 0.48.5",
"windows_x86_64_msvc", "windows_x86_64_msvc 0.48.5",
]
[[package]]
name = "windows-targets"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
dependencies = [
"windows_aarch64_gnullvm 0.52.0",
"windows_aarch64_msvc 0.52.0",
"windows_i686_gnu 0.52.0",
"windows_i686_msvc 0.52.0",
"windows_x86_64_gnu 0.52.0",
"windows_x86_64_gnullvm 0.52.0",
"windows_x86_64_msvc 0.52.0",
] ]
[[package]] [[package]]
@ -867,46 +891,88 @@ version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
[[package]] [[package]]
name = "windows_aarch64_msvc" name = "windows_aarch64_msvc"
version = "0.48.5" version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
[[package]] [[package]]
name = "windows_i686_gnu" name = "windows_i686_gnu"
version = "0.48.5" version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_gnu"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
[[package]] [[package]]
name = "windows_i686_msvc" name = "windows_i686_msvc"
version = "0.48.5" version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_i686_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
[[package]] [[package]]
name = "windows_x86_64_gnu" name = "windows_x86_64_gnu"
version = "0.48.5" version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
[[package]] [[package]]
name = "windows_x86_64_gnullvm" name = "windows_x86_64_gnullvm"
version = "0.48.5" version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
[[package]] [[package]]
name = "windows_x86_64_msvc" name = "windows_x86_64_msvc"
version = "0.48.5" version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
[[package]] [[package]]
name = "wit-bindgen" name = "wit-bindgen"
version = "0.13.1" version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [ dependencies = [
"bitflags 2.4.1", "bitflags 2.4.1",
"wit-bindgen-rust-macro", "wit-bindgen-rust-macro",
@ -914,8 +980,8 @@ dependencies = [
[[package]] [[package]]
name = "wit-bindgen-core" name = "wit-bindgen-core"
version = "0.13.1" version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"wit-component", "wit-component",
@ -924,8 +990,8 @@ dependencies = [
[[package]] [[package]]
name = "wit-bindgen-rust" name = "wit-bindgen-rust"
version = "0.13.2" version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"heck", "heck",
@ -936,13 +1002,13 @@ dependencies = [
[[package]] [[package]]
name = "wit-bindgen-rust-macro" name = "wit-bindgen-rust-macro"
version = "0.13.1" version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.39", "syn 2.0.40",
"wit-bindgen-core", "wit-bindgen-core",
"wit-bindgen-rust", "wit-bindgen-rust",
"wit-component", "wit-component",
@ -950,9 +1016,9 @@ dependencies = [
[[package]] [[package]]
name = "wit-component" name = "wit-component"
version = "0.17.0" version = "0.18.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "480cc1a078b305c1b8510f7c455c76cbd008ee49935f3a6c5fd5e937d8d95b1e" checksum = "5b8a35a2a9992898c9d27f1664001860595a4bc99d32dd3599d547412e17d7e2"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bitflags 2.4.1", "bitflags 2.4.1",
@ -969,9 +1035,9 @@ dependencies = [
[[package]] [[package]]
name = "wit-parser" name = "wit-parser"
version = "0.12.2" version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43771ee863a16ec4ecf9da0fc65c3bbd4a1235c8e3da5f094b562894843dfa76" checksum = "15df6b7b28ce94b8be39d8df5cb21a08a4f3b9f33b631aedb4aa5776f785ead3"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"id-arena", "id-arena",
@ -986,6 +1052,6 @@ dependencies = [
[[package]] [[package]]
name = "zeroize" name = "zeroize"
version = "1.6.0" version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d"

View File

@ -17,10 +17,10 @@ alloy-sol-types = "0.3.2"
bincode = "1.3.3" bincode = "1.3.3"
hex = "0.4.3" hex = "0.4.3"
rmp-serde = "1.1.2" rmp-serde = "1.1.2"
serde = {version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" serde_json = "1.0"
uqbar_process_lib = { git = "ssh://git@github.com/uqbar-dao/process_lib.git", rev = "5e1b94a" } uqbar_process_lib = { git = "ssh://git@github.com/uqbar-dao/process_lib.git", rev = "3ea3a23" }
wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "5390bab780733f1660d14c254ec985df2816bf1d" } wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "efcc759" }
[lib] [lib]
crate-type = ["cdylib"] crate-type = ["cdylib"]

View File

@ -6,7 +6,7 @@ use serde_json::json;
use std::collections::HashMap; use std::collections::HashMap;
use std::string::FromUtf8Error; use std::string::FromUtf8Error;
use uqbar_process_lib::{ use uqbar_process_lib::{
get_typed_state, http, receive, set_state, Address, Message, Payload, Request, Response, await_message, get_typed_state, http, set_state, Address, Message, Payload, Request, Response,
}; };
wit_bindgen::generate!({ wit_bindgen::generate!({
@ -157,18 +157,18 @@ fn main(our: Address, mut state: State) -> anyhow::Result<()> {
http::bind_http_path("/node/:name", false, false)?; http::bind_http_path("/node/:name", false, false)?;
loop { loop {
let Ok((source, message)) = receive() else { let Ok(message) = await_message() else {
println!("qns_indexer: got network error"); println!("qns_indexer: got network error");
continue; continue;
}; };
let Message::Request(request) = message else { let Message::Request { source, ipc, .. } = message else {
// TODO we should store the subscription ID for eth_rpc // TODO we should store the subscription ID for eth_rpc
// incase we want to cancel/reset it // incase we want to cancel/reset it
continue; continue;
}; };
if source.process == "http_server:sys:uqbar" { if source.process == "http_server:sys:uqbar" {
if let Ok(ipc_json) = serde_json::from_slice::<serde_json::Value>(&request.ipc) { if let Ok(ipc_json) = serde_json::from_slice::<serde_json::Value>(&ipc) {
if ipc_json["path"].as_str().unwrap_or_default() == "/node/:name" { if ipc_json["path"].as_str().unwrap_or_default() == "/node/:name" {
if let Some(name) = ipc_json["url_params"]["name"].as_str() { if let Some(name) = ipc_json["url_params"]["name"].as_str() {
if let Some(node) = state.nodes.get(name) { if let Some(node) = state.nodes.get(name) {
@ -211,7 +211,7 @@ fn main(our: Address, mut state: State) -> anyhow::Result<()> {
continue; continue;
} }
let Ok(msg) = serde_json::from_slice::<AllActions>(&request.ipc) else { let Ok(msg) = serde_json::from_slice::<AllActions>(&ipc) else {
println!("qns_indexer: got invalid message"); println!("qns_indexer: got invalid message");
continue; continue;
}; };

View File

@ -58,9 +58,9 @@ dependencies = [
[[package]] [[package]]
name = "getrandom" name = "getrandom"
version = "0.2.10" version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
@ -69,9 +69,9 @@ dependencies = [
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.14.2" version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
[[package]] [[package]]
name = "heck" name = "heck"
@ -122,9 +122,9 @@ dependencies = [
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "1.0.9" version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
[[package]] [[package]]
name = "leb128" name = "leb128"
@ -134,9 +134,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.149" version = "0.2.151"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4"
[[package]] [[package]]
name = "log" name = "log"
@ -158,9 +158,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.69" version = "1.0.70"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
@ -206,9 +206,9 @@ dependencies = [
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.15" version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
[[package]] [[package]]
name = "semver" name = "semver"
@ -218,18 +218,18 @@ checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.190" version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.190" version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -249,9 +249,9 @@ dependencies = [
[[package]] [[package]]
name = "smallvec" name = "smallvec"
version = "1.11.1" version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
[[package]] [[package]]
name = "spdx" name = "spdx"
@ -264,9 +264,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.38" version = "2.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" checksum = "13fa70a4ee923979ffb522cacce59d34421ebdea5625e1073c4326ef9d2dd42e"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -322,9 +322,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]] [[package]]
name = "unicode-bidi" name = "unicode-bidi"
version = "0.3.13" version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416"
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
@ -355,8 +355,8 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
[[package]] [[package]]
name = "uqbar_process_lib" name = "uqbar_process_lib"
version = "0.3.0" version = "0.4.0"
source = "git+ssh://git@github.com/uqbar-dao/process_lib.git?rev=5e1b94a#5e1b94ae2f85c66da33ec52117a72b90d53c4d22" source = "git+ssh://git@github.com/uqbar-dao/process_lib.git?rev=3ea3a23#3ea3a23de46cda8ebe1ea8f3b9f764b57e7feada"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bincode", "bincode",
@ -388,18 +388,18 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]] [[package]]
name = "wasm-encoder" name = "wasm-encoder"
version = "0.36.1" version = "0.38.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53ae0be20bf87918df4fa831bfbbd0b491d24aee407ed86360eae4c2c5608d38" checksum = "0ad2b51884de9c7f4fe2fd1043fccb8dcad4b1e29558146ee57a144d15779f3f"
dependencies = [ dependencies = [
"leb128", "leb128",
] ]
[[package]] [[package]]
name = "wasm-metadata" name = "wasm-metadata"
version = "0.10.10" version = "0.10.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5621910462c61a8efc3248fdfb1739bf649bb335b0df935c27b340418105f9d8" checksum = "d835d67708f6374937c550ad8dd1d17c616ae009e3f00d7a0ac9f7825e78c36a"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"indexmap", "indexmap",
@ -413,9 +413,9 @@ dependencies = [
[[package]] [[package]]
name = "wasmparser" name = "wasmparser"
version = "0.116.0" version = "0.118.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53290b1276c5c2d47d694fb1a920538c01f51690e7e261acbe1d10c5fc306ea1" checksum = "95ee9723b928e735d53000dec9eae7b07a60e490c85ab54abb66659fc61bfcd9"
dependencies = [ dependencies = [
"indexmap", "indexmap",
"semver", "semver",
@ -423,8 +423,8 @@ dependencies = [
[[package]] [[package]]
name = "wit-bindgen" name = "wit-bindgen"
version = "0.13.1" version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"wit-bindgen-rust-macro", "wit-bindgen-rust-macro",
@ -432,8 +432,8 @@ dependencies = [
[[package]] [[package]]
name = "wit-bindgen-core" name = "wit-bindgen-core"
version = "0.13.1" version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"wit-component", "wit-component",
@ -442,8 +442,8 @@ dependencies = [
[[package]] [[package]]
name = "wit-bindgen-rust" name = "wit-bindgen-rust"
version = "0.13.2" version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"heck", "heck",
@ -454,8 +454,8 @@ dependencies = [
[[package]] [[package]]
name = "wit-bindgen-rust-macro" name = "wit-bindgen-rust-macro"
version = "0.13.1" version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"proc-macro2", "proc-macro2",
@ -468,9 +468,9 @@ dependencies = [
[[package]] [[package]]
name = "wit-component" name = "wit-component"
version = "0.17.0" version = "0.18.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "480cc1a078b305c1b8510f7c455c76cbd008ee49935f3a6c5fd5e937d8d95b1e" checksum = "5b8a35a2a9992898c9d27f1664001860595a4bc99d32dd3599d547412e17d7e2"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bitflags", "bitflags",
@ -487,9 +487,9 @@ dependencies = [
[[package]] [[package]]
name = "wit-parser" name = "wit-parser"
version = "0.12.2" version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43771ee863a16ec4ecf9da0fc65c3bbd4a1235c8e3da5f094b562894843dfa76" checksum = "15df6b7b28ce94b8be39d8df5cb21a08a4f3b9f33b631aedb4aa5776f785ead3"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"id-arena", "id-arena",

View File

@ -13,10 +13,10 @@ lto = true
[dependencies] [dependencies]
anyhow = "1.0" anyhow = "1.0"
bincode = "1.3.3" bincode = "1.3.3"
serde = {version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" serde_json = "1.0"
uqbar_process_lib = { git = "ssh://git@github.com/uqbar-dao/process_lib.git", rev = "5e1b94a" } uqbar_process_lib = { git = "ssh://git@github.com/uqbar-dao/process_lib.git", rev = "3ea3a23" }
wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "5390bab780733f1660d14c254ec985df2816bf1d" } wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "efcc759" }
[lib] [lib]
crate-type = ["cdylib"] crate-type = ["cdylib"]

View File

@ -19,9 +19,9 @@ dependencies = [
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "2.4.0" version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
[[package]] [[package]]
name = "bytes" name = "bytes"
@ -58,9 +58,9 @@ dependencies = [
[[package]] [[package]]
name = "getrandom" name = "getrandom"
version = "0.2.10" version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
@ -69,9 +69,9 @@ dependencies = [
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.14.0" version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
[[package]] [[package]]
name = "heck" name = "heck"
@ -111,9 +111,9 @@ dependencies = [
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "2.0.0" version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f"
dependencies = [ dependencies = [
"equivalent", "equivalent",
"hashbrown", "hashbrown",
@ -122,9 +122,9 @@ dependencies = [
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "1.0.9" version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
[[package]] [[package]]
name = "leb128" name = "leb128"
@ -134,9 +134,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.150" version = "0.2.151"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4"
[[package]] [[package]]
name = "log" name = "log"
@ -158,9 +158,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.66" version = "1.0.70"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
@ -206,30 +206,30 @@ dependencies = [
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.15" version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
[[package]] [[package]]
name = "semver" name = "semver"
version = "1.0.18" version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.188" version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.188" version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -238,9 +238,9 @@ dependencies = [
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.105" version = "1.0.108"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b"
dependencies = [ dependencies = [
"itoa", "itoa",
"ryu", "ryu",
@ -249,9 +249,9 @@ dependencies = [
[[package]] [[package]]
name = "smallvec" name = "smallvec"
version = "1.11.0" version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
[[package]] [[package]]
name = "spdx" name = "spdx"
@ -264,9 +264,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.31" version = "2.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "718fa2415bcb8d8bd775917a1bf12a7931b6dfa890753378538118181e0cb398" checksum = "13fa70a4ee923979ffb522cacce59d34421ebdea5625e1073c4326ef9d2dd42e"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -323,15 +323,15 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]] [[package]]
name = "unicode-bidi" name = "unicode-bidi"
version = "0.3.13" version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416"
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
version = "1.0.11" version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]] [[package]]
name = "unicode-normalization" name = "unicode-normalization"
@ -356,8 +356,8 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
[[package]] [[package]]
name = "uqbar_process_lib" name = "uqbar_process_lib"
version = "0.3.0" version = "0.4.0"
source = "git+ssh://git@github.com/uqbar-dao/process_lib.git?rev=5e1b94a#5e1b94ae2f85c66da33ec52117a72b90d53c4d22" source = "git+ssh://git@github.com/uqbar-dao/process_lib.git?rev=3ea3a23#3ea3a23de46cda8ebe1ea8f3b9f764b57e7feada"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bincode", "bincode",
@ -389,18 +389,18 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]] [[package]]
name = "wasm-encoder" name = "wasm-encoder"
version = "0.36.2" version = "0.38.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "822b645bf4f2446b949776ffca47e2af60b167209ffb70814ef8779d299cd421" checksum = "0ad2b51884de9c7f4fe2fd1043fccb8dcad4b1e29558146ee57a144d15779f3f"
dependencies = [ dependencies = [
"leb128", "leb128",
] ]
[[package]] [[package]]
name = "wasm-metadata" name = "wasm-metadata"
version = "0.10.11" version = "0.10.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2167ce53b2faa16a92c6cafd4942cff16c9a4fa0c5a5a0a41131ee4e49fc055f" checksum = "d835d67708f6374937c550ad8dd1d17c616ae009e3f00d7a0ac9f7825e78c36a"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"indexmap", "indexmap",
@ -414,9 +414,9 @@ dependencies = [
[[package]] [[package]]
name = "wasmparser" name = "wasmparser"
version = "0.116.1" version = "0.118.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a58e28b80dd8340cb07b8242ae654756161f6fc8d0038123d679b7b99964fa50" checksum = "95ee9723b928e735d53000dec9eae7b07a60e490c85ab54abb66659fc61bfcd9"
dependencies = [ dependencies = [
"indexmap", "indexmap",
"semver", "semver",
@ -424,8 +424,8 @@ dependencies = [
[[package]] [[package]]
name = "wit-bindgen" name = "wit-bindgen"
version = "0.13.1" version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"wit-bindgen-rust-macro", "wit-bindgen-rust-macro",
@ -433,8 +433,8 @@ dependencies = [
[[package]] [[package]]
name = "wit-bindgen-core" name = "wit-bindgen-core"
version = "0.13.1" version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"wit-component", "wit-component",
@ -443,8 +443,8 @@ dependencies = [
[[package]] [[package]]
name = "wit-bindgen-rust" name = "wit-bindgen-rust"
version = "0.13.2" version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"heck", "heck",
@ -455,8 +455,8 @@ dependencies = [
[[package]] [[package]]
name = "wit-bindgen-rust-macro" name = "wit-bindgen-rust-macro"
version = "0.13.1" version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"proc-macro2", "proc-macro2",
@ -469,9 +469,9 @@ dependencies = [
[[package]] [[package]]
name = "wit-component" name = "wit-component"
version = "0.17.0" version = "0.18.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "480cc1a078b305c1b8510f7c455c76cbd008ee49935f3a6c5fd5e937d8d95b1e" checksum = "5b8a35a2a9992898c9d27f1664001860595a4bc99d32dd3599d547412e17d7e2"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bitflags", "bitflags",
@ -488,9 +488,9 @@ dependencies = [
[[package]] [[package]]
name = "wit-parser" name = "wit-parser"
version = "0.12.2" version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43771ee863a16ec4ecf9da0fc65c3bbd4a1235c8e3da5f094b562894843dfa76" checksum = "15df6b7b28ce94b8be39d8df5cb21a08a4f3b9f33b631aedb4aa5776f785ead3"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"id-arena", "id-arena",

View File

@ -13,19 +13,14 @@ lto = true
[dependencies] [dependencies]
anyhow = "1.0" anyhow = "1.0"
bincode = "1.3.3" bincode = "1.3.3"
serde = {version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" serde_json = "1.0"
thiserror = "1.0" thiserror = "1.0"
uqbar_process_lib = { git = "ssh://git@github.com/uqbar-dao/process_lib.git", rev = "5e1b94a" } uqbar_process_lib = { git = "ssh://git@github.com/uqbar-dao/process_lib.git", rev = "3ea3a23" }
wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "5390bab780733f1660d14c254ec985df2816bf1d" } wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "efcc759" }
[lib] [lib]
crate-type = ["cdylib"] crate-type = ["cdylib"]
[package.metadata.component] [package.metadata.component]
package = "uqbar:process" package = "uqbar:process"
[package.metadata.component.target]
path = "wit"
[package.metadata.component.dependencies]

View File

@ -1,7 +1,7 @@
use serde::{Serialize, Deserialize}; use serde::{Serialize, Deserialize};
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use uqbar_process_lib::{Address, ProcessId, Request, Response}; use uqbar_process_lib::{Address, Message, ProcessId, Request, Response};
use uqbar_process_lib::kernel_types as kt; use uqbar_process_lib::kernel_types as kt;
use uqbar_process_lib::uqbar::process::standard as wit; use uqbar_process_lib::uqbar::process::standard as wit;
@ -36,20 +36,20 @@ fn handle_message(our: &Address) -> anyhow::Result<()> {
}, },
wit::Message::Request(wit::Request { ref ipc, .. }) => { wit::Message::Request(wit::Request { ref ipc, .. }) => {
match serde_json::from_slice(ipc)? { match serde_json::from_slice(ipc)? {
tt::TesterRequest::Run(_) => { tt::TesterRequest::Run { test_timeout, .. } => {
wit::print_to_terminal(0, "test_runner: got Run"); wit::print_to_terminal(0, "test_runner: got Run");
let (_, response) = Request::new() let response = Request::new()
.target(make_vfs_address(&our)?) .target(make_vfs_address(&our)?)
.ipc(serde_json::to_vec(&kt::VfsRequest { .ipc(serde_json::to_vec(&kt::VfsRequest {
drive: "tester:uqbar".into(), drive: "tester:uqbar".into(),
action: kt::VfsAction::GetEntry("/".into()), action: kt::VfsAction::GetEntry("/".into()),
})?) })?)
.send_and_await_response(5)??; .send_and_await_response(test_timeout)?.unwrap();
let wit::Message::Response((response, _)) = response else { panic!("") }; let Message::Response { ipc: vfs_ipc, .. } = response else { panic!("") };
let kt::VfsResponse::GetEntry { children, .. } = let kt::VfsResponse::GetEntry { children, .. } =
serde_json::from_slice(&response.ipc)? else { panic!("") }; serde_json::from_slice(&vfs_ipc)? else { panic!("") };
let mut children: HashSet<_> = children.into_iter().collect(); let mut children: HashSet<_> = children.into_iter().collect();
children.remove("/manifest.json"); children.remove("/manifest.json");
children.remove("/metadata.json"); children.remove("/metadata.json");
@ -73,16 +73,16 @@ fn handle_message(our: &Address) -> anyhow::Result<()> {
} }
}; };
let (_, response) = Request::new() let response = Request::new()
.target(Address { .target(Address {
node: our.node.clone(), node: our.node.clone(),
process: child_process_id, process: child_process_id,
}) })
.ipc(ipc.clone()) .ipc(ipc.clone())
.send_and_await_response(5)??; .send_and_await_response(test_timeout)?.unwrap();
let wit::Message::Response((response, _)) = response else { panic!("") }; let Message::Response { ipc, .. } = response else { panic!("") };
match serde_json::from_slice(&response.ipc)? { match serde_json::from_slice(&ipc)? {
tt::TesterResponse::Pass => {}, tt::TesterResponse::Pass => {},
tt::TesterResponse::GetFullMessage(_) => {}, tt::TesterResponse::GetFullMessage(_) => {},
tt::TesterResponse::Fail { test, file, line, column } => { tt::TesterResponse::Fail { test, file, line, column } => {

View File

@ -19,9 +19,9 @@ dependencies = [
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "2.4.0" version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
[[package]] [[package]]
name = "bytes" name = "bytes"
@ -58,9 +58,9 @@ dependencies = [
[[package]] [[package]]
name = "getrandom" name = "getrandom"
version = "0.2.10" version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
@ -69,9 +69,9 @@ dependencies = [
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.14.2" version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
[[package]] [[package]]
name = "heck" name = "heck"
@ -122,9 +122,9 @@ dependencies = [
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "1.0.9" version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
[[package]] [[package]]
name = "leb128" name = "leb128"
@ -134,9 +134,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.150" version = "0.2.151"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4"
[[package]] [[package]]
name = "log" name = "log"
@ -158,9 +158,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.66" version = "1.0.70"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
@ -206,30 +206,30 @@ dependencies = [
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.15" version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
[[package]] [[package]]
name = "semver" name = "semver"
version = "1.0.18" version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.188" version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.188" version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -238,9 +238,9 @@ dependencies = [
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.105" version = "1.0.108"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b"
dependencies = [ dependencies = [
"itoa", "itoa",
"ryu", "ryu",
@ -249,9 +249,9 @@ dependencies = [
[[package]] [[package]]
name = "smallvec" name = "smallvec"
version = "1.11.0" version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
[[package]] [[package]]
name = "spdx" name = "spdx"
@ -264,9 +264,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.31" version = "2.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "718fa2415bcb8d8bd775917a1bf12a7931b6dfa890753378538118181e0cb398" checksum = "13fa70a4ee923979ffb522cacce59d34421ebdea5625e1073c4326ef9d2dd42e"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -324,15 +324,15 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]] [[package]]
name = "unicode-bidi" name = "unicode-bidi"
version = "0.3.13" version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416"
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
version = "1.0.11" version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]] [[package]]
name = "unicode-normalization" name = "unicode-normalization"
@ -357,8 +357,8 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
[[package]] [[package]]
name = "uqbar_process_lib" name = "uqbar_process_lib"
version = "0.3.0" version = "0.4.0"
source = "git+ssh://git@github.com/uqbar-dao/process_lib.git?rev=5e1b94a#5e1b94ae2f85c66da33ec52117a72b90d53c4d22" source = "git+ssh://git@github.com/uqbar-dao/process_lib.git?rev=3ea3a23#3ea3a23de46cda8ebe1ea8f3b9f764b57e7feada"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bincode", "bincode",
@ -390,18 +390,18 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]] [[package]]
name = "wasm-encoder" name = "wasm-encoder"
version = "0.36.2" version = "0.38.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "822b645bf4f2446b949776ffca47e2af60b167209ffb70814ef8779d299cd421" checksum = "0ad2b51884de9c7f4fe2fd1043fccb8dcad4b1e29558146ee57a144d15779f3f"
dependencies = [ dependencies = [
"leb128", "leb128",
] ]
[[package]] [[package]]
name = "wasm-metadata" name = "wasm-metadata"
version = "0.10.11" version = "0.10.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2167ce53b2faa16a92c6cafd4942cff16c9a4fa0c5a5a0a41131ee4e49fc055f" checksum = "d835d67708f6374937c550ad8dd1d17c616ae009e3f00d7a0ac9f7825e78c36a"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"indexmap", "indexmap",
@ -415,9 +415,9 @@ dependencies = [
[[package]] [[package]]
name = "wasmparser" name = "wasmparser"
version = "0.116.1" version = "0.118.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a58e28b80dd8340cb07b8242ae654756161f6fc8d0038123d679b7b99964fa50" checksum = "95ee9723b928e735d53000dec9eae7b07a60e490c85ab54abb66659fc61bfcd9"
dependencies = [ dependencies = [
"indexmap", "indexmap",
"semver", "semver",
@ -425,8 +425,8 @@ dependencies = [
[[package]] [[package]]
name = "wit-bindgen" name = "wit-bindgen"
version = "0.13.1" version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"wit-bindgen-rust-macro", "wit-bindgen-rust-macro",
@ -434,8 +434,8 @@ dependencies = [
[[package]] [[package]]
name = "wit-bindgen-core" name = "wit-bindgen-core"
version = "0.13.1" version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"wit-component", "wit-component",
@ -444,8 +444,8 @@ dependencies = [
[[package]] [[package]]
name = "wit-bindgen-rust" name = "wit-bindgen-rust"
version = "0.13.2" version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"heck", "heck",
@ -456,8 +456,8 @@ dependencies = [
[[package]] [[package]]
name = "wit-bindgen-rust-macro" name = "wit-bindgen-rust-macro"
version = "0.13.1" version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"proc-macro2", "proc-macro2",
@ -470,9 +470,9 @@ dependencies = [
[[package]] [[package]]
name = "wit-component" name = "wit-component"
version = "0.17.0" version = "0.18.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "480cc1a078b305c1b8510f7c455c76cbd008ee49935f3a6c5fd5e937d8d95b1e" checksum = "5b8a35a2a9992898c9d27f1664001860595a4bc99d32dd3599d547412e17d7e2"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bitflags", "bitflags",
@ -489,9 +489,9 @@ dependencies = [
[[package]] [[package]]
name = "wit-parser" name = "wit-parser"
version = "0.12.2" version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43771ee863a16ec4ecf9da0fc65c3bbd4a1235c8e3da5f094b562894843dfa76" checksum = "15df6b7b28ce94b8be39d8df5cb21a08a4f3b9f33b631aedb4aa5776f785ead3"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"id-arena", "id-arena",

View File

@ -14,19 +14,14 @@ lto = true
anyhow = "1.0" anyhow = "1.0"
bincode = "1.3.3" bincode = "1.3.3"
indexmap = "2.1" indexmap = "2.1"
serde = {version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" serde_json = "1.0"
thiserror = "1.0" thiserror = "1.0"
uqbar_process_lib = { git = "ssh://git@github.com/uqbar-dao/process_lib.git", rev = "5e1b94a" } uqbar_process_lib = { git = "ssh://git@github.com/uqbar-dao/process_lib.git", rev = "3ea3a23" }
wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "5390bab780733f1660d14c254ec985df2816bf1d" } wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "efcc759" }
[lib] [lib]
crate-type = ["cdylib"] crate-type = ["cdylib"]
[package.metadata.component] [package.metadata.component]
package = "uqbar:process" package = "uqbar:process"
[package.metadata.component.target]
path = "wit"
[package.metadata.component.dependencies]

View File

@ -50,7 +50,7 @@ fn handle_message(
}, },
wit::Message::Request(wit::Request { ipc, .. }) => { wit::Message::Request(wit::Request { ipc, .. }) => {
match serde_json::from_slice(&ipc)? { match serde_json::from_slice(&ipc)? {
tt::TesterRequest::Run(input_node_names) => { tt::TesterRequest::Run { input_node_names, test_timeout } => {
wit::print_to_terminal(0, "tester: got Run"); wit::print_to_terminal(0, "tester: got Run");
assert!(input_node_names.len() >= 1); assert!(input_node_names.len() >= 1);
@ -83,7 +83,7 @@ fn handle_message(
process: child_process_id, process: child_process_id,
}) })
.ipc(ipc) .ipc(ipc)
.expects_response(15) .expects_response(test_timeout)
.send()?; .send()?;
} }
}, },

View File

@ -19,7 +19,7 @@ pub struct KernelMessage {
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub enum TesterRequest { pub enum TesterRequest {
Run(Vec<String>), Run { input_node_names: Vec<String>, test_timeout: u64 },
KernelMessage(KernelMessage), KernelMessage(KernelMessage),
GetFullMessage(kt::Message), GetFullMessage(kt::Message),
} }
@ -61,6 +61,7 @@ macro_rules! fail {
}).unwrap()) }).unwrap())
.send() .send()
.unwrap(); .unwrap();
panic!("")
}; };
($test:expr, $file:expr, $line:expr, $column:expr) => { ($test:expr, $file:expr, $line:expr, $column:expr) => {
Response::new() Response::new()
@ -72,6 +73,6 @@ macro_rules! fail {
}).unwrap()) }).unwrap())
.send() .send()
.unwrap(); .unwrap();
panic!(""); panic!("")
}; };
} }

View File

@ -136,38 +136,36 @@ async fn handle_message(
match client.execute(request).await { match client.execute(request).await {
Ok(response) => { Ok(response) => {
if expects_response.is_some() { let _ = send_to_loop
let _ = send_to_loop .send(KernelMessage {
.send(KernelMessage { id,
id, source: Address {
source: Address { node: our.to_string(),
node: our.to_string(), process: ProcessId::new(Some("http_client"), "sys", "uqbar"),
process: ProcessId::new(Some("http_client"), "sys", "uqbar"), },
target,
rsvp: None,
message: Message::Response((
Response {
inherit: false,
ipc: serde_json::to_vec::<Result<HttpResponse, HttpClientError>>(&Ok(
HttpResponse {
status: response.status().as_u16(),
headers: serialize_headers(response.headers()),
},
))
.unwrap(),
metadata: None,
}, },
target, None,
rsvp: None, )),
message: Message::Response(( payload: Some(Payload {
Response { mime: None,
inherit: false, bytes: response.bytes().await.unwrap_or_default().to_vec(),
ipc: serde_json::to_vec::<Result<HttpResponse, HttpClientError>>( }),
&Ok(HttpResponse { signed_capabilities: None,
status: response.status().as_u16(), })
headers: serialize_headers(response.headers()), .await;
}),
)
.unwrap(),
metadata: None,
},
None,
)),
payload: Some(Payload {
mime: None,
bytes: response.bytes().await.unwrap_or_default().to_vec(),
}),
signed_capabilities: None,
})
.await;
}
} }
Err(e) => { Err(e) => {
make_error_message( make_error_message(

298
src/http/login.html Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,11 +1,13 @@
use crate::http::types::*; use crate::http::types::*;
use crate::http::utils::*; use crate::http::utils::*;
use crate::register;
use crate::types::*; use crate::types::*;
use crate::{keygen, register};
use anyhow::Result; use anyhow::Result;
use dashmap::DashMap; use dashmap::DashMap;
use futures::{SinkExt, StreamExt}; use futures::{SinkExt, StreamExt};
use http::uri::Authority;
use route_recognizer::Router; use route_recognizer::Router;
use sha2::{Digest, Sha256};
use std::collections::HashMap; use std::collections::HashMap;
use std::net::SocketAddr; use std::net::SocketAddr;
use std::sync::Arc; use std::sync::Arc;
@ -14,7 +16,12 @@ use warp::http::{header::HeaderValue, StatusCode};
use warp::ws::{WebSocket, Ws}; use warp::ws::{WebSocket, Ws};
use warp::{Filter, Reply}; use warp::{Filter, Reply};
#[cfg(not(feature = "simulation-mode"))]
const HTTP_SELF_IMPOSED_TIMEOUT: u64 = 15; const HTTP_SELF_IMPOSED_TIMEOUT: u64 = 15;
#[cfg(feature = "simulation-mode")]
const HTTP_SELF_IMPOSED_TIMEOUT: u64 = 600;
const LOGIN_HTML: &str = include_str!("login.html");
/// mapping from a given HTTP request (assigned an ID) to the oneshot /// mapping from a given HTTP request (assigned an ID) to the oneshot
/// channel that will get a response from the app that handles the request, /// channel that will get a response from the app that handles the request,
@ -32,6 +39,7 @@ type PathBindings = Arc<RwLock<Router<BoundPath>>>;
struct BoundPath { struct BoundPath {
pub app: ProcessId, pub app: ProcessId,
pub secure_subdomain: Option<String>,
pub authenticated: bool, pub authenticated: bool,
pub local_only: bool, pub local_only: bool,
pub static_content: Option<Payload>, // TODO store in filesystem and cache pub static_content: Option<Payload>, // TODO store in filesystem and cache
@ -55,26 +63,28 @@ struct BoundPath {
pub async fn http_server( pub async fn http_server(
our_name: String, our_name: String,
our_port: u16, our_port: u16,
encoded_keyfile: Vec<u8>,
jwt_secret_bytes: Vec<u8>, jwt_secret_bytes: Vec<u8>,
mut recv_in_server: MessageReceiver, mut recv_in_server: MessageReceiver,
send_to_loop: MessageSender, send_to_loop: MessageSender,
print_tx: PrintSender, print_tx: PrintSender,
) -> Result<()> { ) -> Result<()> {
let our_name = Arc::new(our_name); let our_name = Arc::new(our_name);
let encoded_keyfile = Arc::new(encoded_keyfile);
let jwt_secret_bytes = Arc::new(jwt_secret_bytes); let jwt_secret_bytes = Arc::new(jwt_secret_bytes);
let http_response_senders: HttpResponseSenders = Arc::new(DashMap::new()); let http_response_senders: HttpResponseSenders = Arc::new(DashMap::new());
let ws_senders: WebSocketSenders = Arc::new(DashMap::new()); let ws_senders: WebSocketSenders = Arc::new(DashMap::new());
// Add RPC path // add RPC path
let mut bindings_map: Router<BoundPath> = Router::new(); let mut bindings_map: Router<BoundPath> = Router::new();
let rpc_bound_path = BoundPath { let rpc_bound_path = BoundPath {
app: ProcessId::from_str("rpc:sys:uqbar").unwrap(), app: ProcessId::from_str("rpc:sys:uqbar").unwrap(),
secure_subdomain: None, // TODO maybe RPC should have subdomain?
authenticated: false, authenticated: false,
local_only: true, local_only: true,
static_content: None, static_content: None,
}; };
bindings_map.add("/rpc:sys:uqbar/message", rpc_bound_path); bindings_map.add("/rpc:sys:uqbar/message", rpc_bound_path);
let path_bindings: PathBindings = Arc::new(RwLock::new(bindings_map)); let path_bindings: PathBindings = Arc::new(RwLock::new(bindings_map));
tokio::spawn(serve( tokio::spawn(serve(
@ -83,6 +93,7 @@ pub async fn http_server(
http_response_senders.clone(), http_response_senders.clone(),
path_bindings.clone(), path_bindings.clone(),
ws_senders.clone(), ws_senders.clone(),
encoded_keyfile.clone(),
jwt_secret_bytes.clone(), jwt_secret_bytes.clone(),
send_to_loop.clone(), send_to_loop.clone(),
print_tx.clone(), print_tx.clone(),
@ -95,9 +106,7 @@ pub async fn http_server(
http_response_senders.clone(), http_response_senders.clone(),
path_bindings.clone(), path_bindings.clone(),
ws_senders.clone(), ws_senders.clone(),
jwt_secret_bytes.clone(),
send_to_loop.clone(), send_to_loop.clone(),
print_tx.clone(),
) )
.await; .await;
} }
@ -112,6 +121,7 @@ async fn serve(
http_response_senders: HttpResponseSenders, http_response_senders: HttpResponseSenders,
path_bindings: PathBindings, path_bindings: PathBindings,
ws_senders: WebSocketSenders, ws_senders: WebSocketSenders,
encoded_keyfile: Arc<Vec<u8>>,
jwt_secret_bytes: Arc<Vec<u8>>, jwt_secret_bytes: Arc<Vec<u8>>,
send_to_loop: MessageSender, send_to_loop: MessageSender,
print_tx: PrintSender, print_tx: PrintSender,
@ -123,7 +133,7 @@ async fn serve(
}) })
.await; .await;
// Filter to receive websockets // filter to receive websockets
let cloned_msg_tx = send_to_loop.clone(); let cloned_msg_tx = send_to_loop.clone();
let cloned_our = our.clone(); let cloned_our = our.clone();
let cloned_jwt_secret_bytes = jwt_secret_bytes.clone(); let cloned_jwt_secret_bytes = jwt_secret_bytes.clone();
@ -155,10 +165,26 @@ async fn serve(
}) })
}, },
); );
// Filter to receive HTTP requests
// filter to receive and handle login requests
let cloned_our = our.clone();
let login = warp::path("login").and(warp::path::end()).and(
warp::get()
.map(|| warp::reply::with_status(warp::reply::html(LOGIN_HTML), StatusCode::OK))
.or(warp::post()
.and(warp::body::content_length_limit(1024 * 16))
.and(warp::body::json())
.and(warp::any().map(move || cloned_our.clone()))
.and(warp::any().map(move || encoded_keyfile.clone()))
.and_then(login_handler)),
);
// filter to receive all other HTTP requests
let filter = warp::filters::method::method() let filter = warp::filters::method::method()
.and(warp::addr::remote()) .and(warp::addr::remote())
.and(warp::filters::host::optional())
.and(warp::path::full()) .and(warp::path::full())
.and(warp::query::<HashMap<String, String>>())
.and(warp::filters::header::headers_cloned()) .and(warp::filters::header::headers_cloned())
.and(warp::filters::body::bytes()) .and(warp::filters::body::bytes())
.and(warp::any().map(move || our.clone())) .and(warp::any().map(move || our.clone()))
@ -166,18 +192,70 @@ async fn serve(
.and(warp::any().map(move || path_bindings.clone())) .and(warp::any().map(move || path_bindings.clone()))
.and(warp::any().map(move || jwt_secret_bytes.clone())) .and(warp::any().map(move || jwt_secret_bytes.clone()))
.and(warp::any().map(move || send_to_loop.clone())) .and(warp::any().map(move || send_to_loop.clone()))
.and(warp::any().map(move || print_tx.clone()))
.and_then(http_handler); .and_then(http_handler);
let filter_with_ws = ws_route.or(filter); let filter_with_ws = ws_route.or(login).or(filter);
warp::serve(filter_with_ws) warp::serve(filter_with_ws)
.run(([0, 0, 0, 0], our_port)) .run(([0, 0, 0, 0], our_port))
.await; .await;
} }
/// handle non-GET requests on /login. if POST, validate password
/// and return auth token, which will be stored in a cookie.
/// then redirect to wherever they were trying to go.
async fn login_handler(
info: LoginInfo,
our: Arc<String>,
encoded_keyfile: Arc<Vec<u8>>,
) -> Result<impl warp::Reply, warp::Rejection> {
match keygen::decode_keyfile(&encoded_keyfile, &info.password) {
Ok(keyfile) => {
let token = match register::generate_jwt(&keyfile.jwt_secret_bytes, our.as_ref()) {
Some(token) => token,
None => {
return Ok(warp::reply::with_status(
warp::reply::json(&"Failed to generate JWT"),
StatusCode::SERVICE_UNAVAILABLE,
)
.into_response())
}
};
let mut response = warp::reply::with_status(
warp::reply::json(&base64::encode(encoded_keyfile.to_vec())),
StatusCode::FOUND,
)
.into_response();
match HeaderValue::from_str(&format!("uqbar-auth_{}={};", our.as_ref(), &token)) {
Ok(v) => {
response.headers_mut().append(http::header::SET_COOKIE, v);
Ok(response)
}
Err(_) => {
return Ok(warp::reply::with_status(
warp::reply::json(&"Failed to generate Auth JWT"),
StatusCode::INTERNAL_SERVER_ERROR,
)
.into_response())
}
}
}
Err(_) => Ok(warp::reply::with_status(
warp::reply::json(&"Failed to decode keyfile"),
StatusCode::INTERNAL_SERVER_ERROR,
)
.into_response()),
}
}
async fn http_handler( async fn http_handler(
method: warp::http::Method, method: warp::http::Method,
socket_addr: Option<SocketAddr>, socket_addr: Option<SocketAddr>,
host: Option<Authority>,
path: warp::path::FullPath, path: warp::path::FullPath,
query_params: HashMap<String, String>,
headers: warp::http::HeaderMap, headers: warp::http::HeaderMap,
body: warp::hyper::body::Bytes, body: warp::hyper::body::Bytes,
our: Arc<String>, our: Arc<String>,
@ -185,11 +263,18 @@ async fn http_handler(
path_bindings: PathBindings, path_bindings: PathBindings,
jwt_secret_bytes: Arc<Vec<u8>>, jwt_secret_bytes: Arc<Vec<u8>>,
send_to_loop: MessageSender, send_to_loop: MessageSender,
print_tx: PrintSender,
) -> Result<impl warp::Reply, warp::Rejection> { ) -> Result<impl warp::Reply, warp::Rejection> {
// TODO this is all so dirty. Figure out what actually matters. // TODO this is all so dirty. Figure out what actually matters.
// trim trailing "/" // trim trailing "/"
let original_path = normalize_path(path.as_str()); let original_path = normalize_path(path.as_str());
let _ = print_tx
.send(Printout {
verbosity: 1,
content: format!("got request for path {original_path}"),
})
.await;
let id: u64 = rand::random(); let id: u64 = rand::random();
let serialized_headers = serialize_headers(&headers); let serialized_headers = serialize_headers(&headers);
let path_bindings = path_bindings.read().await; let path_bindings = path_bindings.read().await;
@ -200,11 +285,55 @@ async fn http_handler(
let bound_path = route.handler(); let bound_path = route.handler();
if bound_path.authenticated { if bound_path.authenticated {
let auth_token = serialized_headers match serialized_headers.get("cookie") {
.get("cookie") Some(auth_token) => {
.cloned() // they have an auth token, validate
.unwrap_or_default(); if !auth_cookie_valid(&our, &auth_token, &jwt_secret_bytes) {
if !auth_cookie_valid(&our, &auth_token, &jwt_secret_bytes) { return Ok(
warp::reply::with_status(vec![], StatusCode::UNAUTHORIZED).into_response()
);
}
}
None => {
// redirect to login page so they can get an auth token
let _ = print_tx
.send(Printout {
verbosity: 1,
content: format!("redirecting request from {socket_addr:?} to login page"),
})
.await;
return Ok(warp::http::Response::builder()
.status(StatusCode::TEMPORARY_REDIRECT)
.header(
"Location",
format!(
"http://{}/login",
host.unwrap_or(Authority::from_static("localhost"))
),
)
.body(vec![])
.into_response());
}
}
}
if let Some(ref subdomain) = bound_path.secure_subdomain {
let _ = print_tx
.send(Printout {
verbosity: 1,
content: format!(
"got request for path {original_path} bound by subdomain {subdomain}"
),
})
.await;
// assert that host matches what this app wants it to be
if host.is_none() {
return Ok(warp::reply::with_status(vec![], StatusCode::UNAUTHORIZED).into_response());
}
let host = host.as_ref().unwrap();
// parse out subdomain from host (there can only be one)
let request_subdomain = host.host().split('.').next().unwrap_or("");
if request_subdomain != subdomain {
return Ok(warp::reply::with_status(vec![], StatusCode::UNAUTHORIZED).into_response()); return Ok(warp::reply::with_status(vec![], StatusCode::UNAUTHORIZED).into_response());
} }
} }
@ -258,14 +387,20 @@ async fn http_handler(
message: Message::Request(Request { message: Message::Request(Request {
inherit: false, inherit: false,
expects_response: Some(HTTP_SELF_IMPOSED_TIMEOUT), expects_response: Some(HTTP_SELF_IMPOSED_TIMEOUT),
ipc: serde_json::to_vec(&IncomingHttpRequest { ipc: serde_json::to_vec(&HttpServerRequest::Http(IncomingHttpRequest {
source_socket_addr: socket_addr.map(|addr| addr.to_string()), source_socket_addr: socket_addr.map(|addr| addr.to_string()),
method: method.to_string(), method: method.to_string(),
raw_path: format!("http://localhost{}", original_path), raw_path: format!(
"http://{}{}",
host.unwrap_or(Authority::from_static("localhost"))
.to_string(),
original_path
),
headers: serialized_headers, headers: serialized_headers,
}) query_params,
}))
.unwrap(), .unwrap(),
metadata: None, metadata: Some("http".into()),
}), }),
payload: Some(Payload { payload: Some(Payload {
mime: None, mime: None,
@ -390,15 +525,28 @@ async fn maintain_websocket(
jwt_secret_bytes: Arc<Vec<u8>>, jwt_secret_bytes: Arc<Vec<u8>>,
ws_senders: WebSocketSenders, ws_senders: WebSocketSenders,
send_to_loop: MessageSender, send_to_loop: MessageSender,
_print_tx: PrintSender, print_tx: PrintSender,
) { ) {
let (mut write_stream, mut read_stream) = ws.split(); let (mut write_stream, mut read_stream) = ws.split();
// first, receive a message from client that contains the target process // first, receive a message from client that contains the target process
// and the auth token // and the auth token
let _ = print_tx
.send(Printout {
verbosity: 1,
content: format!("got new client websocket connection"),
})
.await;
let Some(Ok(register_msg)) = read_stream.next().await else { let Some(Ok(register_msg)) = read_stream.next().await else {
// stream closed, exit // stream closed, exit
let _ = print_tx
.send(Printout {
verbosity: 1,
content: format!("client failed to send registration message"),
})
.await;
let stream = write_stream.reunite(read_stream).unwrap(); let stream = write_stream.reunite(read_stream).unwrap();
let _ = stream.close().await; let _ = stream.close().await;
return; return;
@ -406,6 +554,12 @@ async fn maintain_websocket(
let Ok(ws_register) = serde_json::from_slice::<WsRegister>(register_msg.as_bytes()) else { let Ok(ws_register) = serde_json::from_slice::<WsRegister>(register_msg.as_bytes()) else {
// stream error, exit // stream error, exit
let _ = print_tx
.send(Printout {
verbosity: 1,
content: format!("couldn't parse registration message from client"),
})
.await;
let stream = write_stream.reunite(read_stream).unwrap(); let stream = write_stream.reunite(read_stream).unwrap();
let _ = stream.close().await; let _ = stream.close().await;
return; return;
@ -413,11 +567,24 @@ async fn maintain_websocket(
let Ok(owner_process) = ProcessId::from_str(&ws_register.target_process) else { let Ok(owner_process) = ProcessId::from_str(&ws_register.target_process) else {
// invalid process id, exit // invalid process id, exit
let _ = print_tx
.send(Printout {
verbosity: 1,
content: format!("client sent malformed process ID"),
})
.await;
let stream = write_stream.reunite(read_stream).unwrap(); let stream = write_stream.reunite(read_stream).unwrap();
let _ = stream.close().await; let _ = stream.close().await;
return; return;
}; };
let _ = print_tx
.send(Printout {
verbosity: 1,
content: format!("channel is intended for {owner_process}"),
})
.await;
let Ok(our_name) = verify_auth_token(&ws_register.auth_token, &jwt_secret_bytes) else { let Ok(our_name) = verify_auth_token(&ws_register.auth_token, &jwt_secret_bytes) else {
// invalid auth token, exit // invalid auth token, exit
let stream = write_stream.reunite(read_stream).unwrap(); let stream = write_stream.reunite(read_stream).unwrap();
@ -453,8 +620,8 @@ async fn maintain_websocket(
message: Message::Request(Request { message: Message::Request(Request {
inherit: false, inherit: false,
expects_response: None, expects_response: None,
ipc: serde_json::to_vec(&HttpServerAction::WebSocketOpen(ws_channel_id)).unwrap(), ipc: serde_json::to_vec(&HttpServerRequest::WebSocketOpen(ws_channel_id)).unwrap(),
metadata: None, metadata: Some("ws".into()),
}), }),
payload: None, payload: None,
signed_capabilities: None, signed_capabilities: None,
@ -477,6 +644,13 @@ async fn maintain_websocket(
return; return;
}; };
let _ = print_tx
.send(Printout {
verbosity: 1,
content: format!("websocket channel {ws_channel_id} opened"),
})
.await;
loop { loop {
tokio::select! { tokio::select! {
read = read_stream.next() => { read = read_stream.next() => {
@ -508,11 +682,11 @@ async fn maintain_websocket(
message: Message::Request(Request { message: Message::Request(Request {
inherit: false, inherit: false,
expects_response: None, expects_response: None,
ipc: serde_json::to_vec(&HttpServerAction::WebSocketPush { ipc: serde_json::to_vec(&HttpServerRequest::WebSocketPush {
channel_id: ws_channel_id, channel_id: ws_channel_id,
message_type: WsMessageType::Binary, message_type: WsMessageType::Binary,
}).unwrap(), }).unwrap(),
metadata: None, metadata: Some("ws".into()),
}), }),
payload: Some(Payload { payload: Some(Payload {
mime: None, mime: None,
@ -563,8 +737,8 @@ async fn websocket_close(
message: Message::Request(Request { message: Message::Request(Request {
inherit: false, inherit: false,
expects_response: None, expects_response: None,
ipc: serde_json::to_vec(&HttpServerAction::WebSocketClose(channel_id)).unwrap(), ipc: serde_json::to_vec(&HttpServerRequest::WebSocketClose(channel_id)).unwrap(),
metadata: None, metadata: Some("ws".into()),
}), }),
payload: Some(Payload { payload: Some(Payload {
mime: None, mime: None,
@ -584,9 +758,7 @@ async fn handle_app_message(
http_response_senders: HttpResponseSenders, http_response_senders: HttpResponseSenders,
path_bindings: PathBindings, path_bindings: PathBindings,
ws_senders: WebSocketSenders, ws_senders: WebSocketSenders,
jwt_secret_bytes: Arc<Vec<u8>>,
send_to_loop: MessageSender, send_to_loop: MessageSender,
print_tx: PrintSender,
) { ) {
// when we get a Response, try to match it to an outstanding HTTP // when we get a Response, try to match it to an outstanding HTTP
// request and send it there. // request and send it there.
@ -618,60 +790,10 @@ async fn handle_app_message(
.unwrap(), .unwrap(),
)); ));
} else { } else {
let Ok(mut response) = serde_json::from_slice::<HttpResponse>(&response.ipc) else { let Ok(response) = serde_json::from_slice::<HttpResponse>(&response.ipc) else {
// the receiver will automatically trigger a 503 when sender is dropped. // the receiver will automatically trigger a 503 when sender is dropped.
return; return;
}; };
// XX REFACTOR THIS:
// for the login case, todo refactor out?
let segments: Vec<&str> = path
.split('/')
.filter(|&segment| !segment.is_empty())
.collect();
// If we're getting back a /login from a proxy (or our own node),
// then we should generate a jwt from the secret + the name of the ship,
// and then attach it to a header.
if response.status < 400
&& (segments.len() == 1 || segments.len() == 4)
&& matches!(segments.last(), Some(&"login"))
{
if let Some(auth_cookie) = response.headers.get("set-cookie") {
let mut ws_auth_username = km.source.node.clone();
if segments.len() == 4
&& matches!(segments.first(), Some(&"http-proxy"))
&& matches!(segments.get(1), Some(&"serve"))
{
if let Some(segment) = segments.get(2) {
ws_auth_username = segment.to_string();
}
}
if let Some(token) = register::generate_jwt(
jwt_secret_bytes.to_vec().as_slice(),
ws_auth_username.clone(),
) {
let auth_cookie_with_ws = format!(
"{}; uqbar-ws-auth_{}={};",
auth_cookie,
ws_auth_username.clone(),
token
);
response
.headers
.insert("set-cookie".to_string(), auth_cookie_with_ws);
let _ = print_tx
.send(Printout {
verbosity: 2,
content: format!(
"SET WS AUTH COOKIE WITH USERNAME: {}",
ws_auth_username
),
})
.await;
}
}
}
let _ = sender.send(( let _ = sender.send((
HttpResponse { HttpResponse {
status: response.status, status: response.status,
@ -722,6 +844,7 @@ async fn handle_app_message(
&normalize_path(&path), &normalize_path(&path),
BoundPath { BoundPath {
app: km.source.process.clone(), app: km.source.process.clone(),
secure_subdomain: None,
authenticated, authenticated,
local_only, local_only,
static_content: None, static_content: None,
@ -743,6 +866,7 @@ async fn handle_app_message(
&normalize_path(&path), &normalize_path(&path),
BoundPath { BoundPath {
app: km.source.process.clone(), app: km.source.process.clone(),
secure_subdomain: None,
authenticated, authenticated,
local_only, local_only,
static_content: Some(payload), static_content: Some(payload),
@ -751,6 +875,52 @@ async fn handle_app_message(
} }
send_action_response(km.id, km.source, &send_to_loop, Ok(())).await; send_action_response(km.id, km.source, &send_to_loop, Ok(())).await;
} }
HttpServerAction::SecureBind { path, cache } => {
// the process ID is hashed to generate a unique subdomain
// only the first 32 chars, or 128 bits are used.
// we hash because the process ID can contain many more than
// simply alphanumeric characters that will cause issues as a subdomain.
let process_id_hash =
format!("{:x}", Sha256::digest(km.source.process.to_string()));
let subdomain = process_id_hash.split_at(32).0.to_owned();
let mut path_bindings = path_bindings.write().await;
if !cache {
// trim trailing "/"
path_bindings.add(
&normalize_path(&path),
BoundPath {
app: km.source.process.clone(),
secure_subdomain: Some(subdomain),
authenticated: true,
local_only: false,
static_content: None,
},
);
} else {
let Some(payload) = km.payload else {
send_action_response(
km.id,
km.source,
&send_to_loop,
Err(HttpServerError::NoPayload),
)
.await;
return;
};
// trim trailing "/"
path_bindings.add(
&normalize_path(&path),
BoundPath {
app: km.source.process.clone(),
secure_subdomain: Some(subdomain),
authenticated: true,
local_only: false,
static_content: Some(payload),
},
);
}
send_action_response(km.id, km.source, &send_to_loop, Ok(())).await;
}
HttpServerAction::WebSocketOpen(_) => { HttpServerAction::WebSocketOpen(_) => {
// we cannot receive these, only send them to processes // we cannot receive these, only send them to processes
send_action_response( send_action_response(

View File

@ -5,12 +5,32 @@ use thiserror::Error;
/// HTTP Request type that can be shared over WASM boundary to apps. /// HTTP Request type that can be shared over WASM boundary to apps.
/// This is the one you receive from the `http_server:sys:uqbar` service. /// This is the one you receive from the `http_server:sys:uqbar` service.
#[derive(Debug, Serialize, Deserialize)]
pub enum HttpServerRequest {
Http(IncomingHttpRequest),
/// Processes will receive this kind of request when a client connects to them.
/// If a process does not want this websocket open, they should issue a *request*
/// containing a [`type@HttpServerAction::WebSocketClose`] message and this channel ID.
WebSocketOpen(u32),
/// Processes can both SEND and RECEIVE this kind of request
/// (send as [`type@HttpServerAction::WebSocketPush`]).
/// When received, will contain the message bytes as payload.
WebSocketPush {
channel_id: u32,
message_type: WsMessageType,
},
/// Receiving will indicate that the client closed the socket. Can be sent to close
/// from the server-side, as [`type@HttpServerAction::WebSocketClose`].
WebSocketClose(u32),
}
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct IncomingHttpRequest { pub struct IncomingHttpRequest {
pub source_socket_addr: Option<String>, // will parse to SocketAddr pub source_socket_addr: Option<String>, // will parse to SocketAddr
pub method: String, // will parse to http::Method pub method: String, // will parse to http::Method
pub raw_path: String, pub raw_path: String,
pub headers: HashMap<String, String>, pub headers: HashMap<String, String>,
pub query_params: HashMap<String, String>,
// BODY is stored in the payload, as bytes // BODY is stored in the payload, as bytes
} }
@ -56,8 +76,8 @@ pub enum HttpClientError {
} }
/// Request type sent to `http_server:sys:uqbar` in order to configure it. /// Request type sent to `http_server:sys:uqbar` in order to configure it.
/// You can also send [`WebSocketPush`], which allows you to push messages /// You can also send [`type@HttpServerAction::WebSocketPush`], which
/// across an existing open WebSocket connection. /// allows you to push messages across an existing open WebSocket connection.
/// ///
/// If a response is expected, all HttpServerActions will return a Response /// If a response is expected, all HttpServerActions will return a Response
/// with the shape Result<(), HttpServerActionError> serialized to JSON. /// with the shape Result<(), HttpServerActionError> serialized to JSON.
@ -67,23 +87,41 @@ pub enum HttpServerAction {
/// be the static file to serve at this path. /// be the static file to serve at this path.
Bind { Bind {
path: String, path: String,
/// Set whether the HTTP request needs a valid login cookie, AKA, whether
/// the user needs to be logged in to access this path.
authenticated: bool, authenticated: bool,
/// Set whether requests can be fielded from anywhere, or only the loopback address.
local_only: bool, local_only: bool,
/// Set whether to bind the payload statically to this path. That is, take the
/// payload bytes and serve them as the response to any request to this path.
cache: bool,
},
/// SecureBind expects a payload if and only if `cache` is TRUE. The payload should
/// be the static file to serve at this path.
///
/// SecureBind is the same as Bind, except that it forces requests to be made from
/// the unique subdomain of the process that bound the path. These requests are
/// *always* authenticated, and *never* local_only. The purpose of SecureBind is to
/// serve elements of an app frontend or API in an exclusive manner, such that other
/// apps installed on this node cannot access them. Since the subdomain is unique, it
/// will require the user to be logged in separately to the general domain authentication.
SecureBind {
path: String,
/// Set whether to bind the payload statically to this path. That is, take the
/// payload bytes and serve them as the response to any request to this path.
cache: bool, cache: bool,
}, },
/// Processes will RECEIVE this kind of request when a client connects to them. /// Processes will RECEIVE this kind of request when a client connects to them.
/// If a process does not want this websocket open, they can respond with an
/// [`enum@HttpServerAction::WebSocketClose`] message. /// If a process does not want this websocket open, they should issue a *request*
/// containing a [`type@HttpServerAction::WebSocketClose`] message and this channel ID.
WebSocketOpen(u32), WebSocketOpen(u32),
/// Processes can both SEND and RECEIVE this kind of request.
/// When sent, expects a payload containing the WebSocket message bytes to send. /// When sent, expects a payload containing the WebSocket message bytes to send.
WebSocketPush { WebSocketPush {
channel_id: u32, channel_id: u32,
message_type: WsMessageType, message_type: WsMessageType,
}, },
/// Processes can both SEND and RECEIVE this kind of request. Sending will /// Sending will close a socket the process controls.
/// close a socket the process controls. Receiving will indicate that the
/// client closed the socket.
WebSocketClose(u32), WebSocketClose(u32),
} }

View File

@ -855,7 +855,7 @@ pub async fn kernel(
verbosity: 0, verbosity: 0,
content: format!( content: format!(
"event loop: don't have {} amongst registered processes (got message for it from network)", "event loop: don't have {} amongst registered processes (got message for it from network)",
kernel_message.source.process, kernel_message.target.process,
) )
}) })
.await; .await;

View File

@ -23,7 +23,7 @@ pub fn encode_keyfile(
password: String, password: String,
username: String, username: String,
routers: Vec<String>, routers: Vec<String>,
networking_key: Document, networking_key: &[u8],
jwt: Vec<u8>, jwt: Vec<u8>,
file_key: Vec<u8>, file_key: Vec<u8>,
) -> Vec<u8> { ) -> Vec<u8> {
@ -49,9 +49,7 @@ pub fn encode_keyfile(
let jwt_nonce = Aes256Gcm::generate_nonce(&mut OsRng); let jwt_nonce = Aes256Gcm::generate_nonce(&mut OsRng);
let file_nonce = Aes256Gcm::generate_nonce(&mut OsRng); let file_nonce = Aes256Gcm::generate_nonce(&mut OsRng);
let keyciphertext: Vec<u8> = cipher let keyciphertext: Vec<u8> = cipher.encrypt(&network_nonce, networking_key).unwrap();
.encrypt(&network_nonce, networking_key.as_ref())
.unwrap();
let jwtciphertext: Vec<u8> = cipher.encrypt(&jwt_nonce, jwt.as_ref()).unwrap(); let jwtciphertext: Vec<u8> = cipher.encrypt(&jwt_nonce, jwt.as_ref()).unwrap();
let fileciphertext: Vec<u8> = cipher.encrypt(&file_nonce, file_key.as_ref()).unwrap(); let fileciphertext: Vec<u8> = cipher.encrypt(&file_nonce, file_key.as_ref()).unwrap();
@ -66,9 +64,9 @@ pub fn encode_keyfile(
.unwrap() .unwrap()
} }
pub fn decode_keyfile(keyfile: Vec<u8>, password: &str) -> Result<Keyfile, &'static str> { pub fn decode_keyfile(keyfile: &[u8], password: &str) -> Result<Keyfile, &'static str> {
let (username, routers, salt, key_enc, jwt_enc, file_enc) = let (username, routers, salt, key_enc, jwt_enc, file_enc) =
bincode::deserialize::<(String, Vec<String>, Vec<u8>, Vec<u8>, Vec<u8>, Vec<u8>)>(&keyfile) bincode::deserialize::<(String, Vec<String>, Vec<u8>, Vec<u8>, Vec<u8>, Vec<u8>)>(keyfile)
.map_err(|_| "failed to deserialize keyfile")?; .map_err(|_| "failed to deserialize keyfile")?;
// rederive disk key // rederive disk key
@ -112,9 +110,9 @@ pub fn decode_keyfile(keyfile: Vec<u8>, password: &str) -> Result<Keyfile, &'sta
}) })
} }
pub fn get_username_and_routers(keyfile: Vec<u8>) -> Result<(String, Vec<String>), &'static str> { pub fn get_username_and_routers(keyfile: &[u8]) -> Result<(String, Vec<String>), &'static str> {
let (username, routers, _salt, _key_enc, _jwt_enc, _file_enc) = let (username, routers, _salt, _key_enc, _jwt_enc, _file_enc) =
bincode::deserialize::<(String, Vec<String>, Vec<u8>, Vec<u8>, Vec<u8>, Vec<u8>)>(&keyfile) bincode::deserialize::<(String, Vec<String>, Vec<u8>, Vec<u8>, Vec<u8>, Vec<u8>)>(keyfile)
.map_err(|_| "failed to deserialize keyfile")?; .map_err(|_| "failed to deserialize keyfile")?;
Ok((username, routers)) Ok((username, routers))

View File

@ -1,7 +0,0 @@
# Local LLM Integration
1. Clone and build [llama.cpp](https://github.com/ggerganov/llama.cpp) on the same machine where you will run your uqbar node
- follow their README for details on how to do this. In most cases simply running `make` works
- make sure to get your model as a .gguf file
2. Within the llama.cpp directory, run this command in llama.cpp on the same machine you will run your uqbar node: `./server --port <PORT>`
- Note: you can pass in whatever other command line arguments to the llama cpp server you want depending on your preferences/hardware/model/etc.
3. Run your Uqbar node with `--features llm` and `--llm http://localhost:<PORT>`. For example `cargo +nightly run --features llm --release home --rpc wss://eth-sepolia.g.alchemy.com/v2/<YOUR_API_KEY> --llm http://localhost:<PORT>`

View File

@ -1,180 +0,0 @@
use crate::llm::types::*;
use crate::types::*;
use anyhow::Result;
use reqwest::Response as ReqwestResponse;
mod types;
pub async fn llm(
our_name: String,
send_to_loop: MessageSender,
mut recv_in_client: MessageReceiver,
llm_url: String,
print_tx: PrintSender,
) -> Result<()> {
while let Some(message) = recv_in_client.recv().await {
let KernelMessage {
id,
source,
rsvp,
message:
Message::Request(Request {
expects_response,
ipc,
..
}),
..
} = message.clone()
else {
return Err(anyhow::anyhow!("llm: bad message"));
};
let our_name = our_name.clone();
let llm_url = llm_url.clone();
let send_to_loop = send_to_loop.clone();
let print_tx = print_tx.clone();
tokio::spawn(async move {
if let Err(e) = handle_message(
our_name.clone(),
send_to_loop.clone(),
llm_url.clone(),
id,
rsvp,
expects_response,
source.clone(),
ipc,
print_tx.clone(),
)
.await
{
send_to_loop
.send(make_error_message(our_name.clone(), id, source, e))
.await
.unwrap();
}
});
}
Err(anyhow::anyhow!("llm: exited"))
}
async fn handle_message(
our: String,
send_to_loop: MessageSender,
llm_url: String,
id: u64,
rsvp: Option<Address>,
expects_response: Option<u64>,
source: Address,
json: Vec<u8>,
_print_tx: PrintSender,
) -> Result<(), LlmError> {
let target = if expects_response.is_some() {
source.clone()
} else if source.process == ProcessId::from_str("terminal:terminal:uqbar").unwrap() {
source.clone()
} else {
let Some(rsvp) = rsvp else {
return Err(LlmError::BadRsvp);
};
rsvp.clone()
};
let req: LlmPrompt = match serde_json::from_slice(&json) {
Ok(req) => req,
Err(e) => {
return Err(LlmError::BadJson {
json: String::from_utf8(json).unwrap_or_default(),
error: format!("{}", e),
})
}
};
let client = reqwest::Client::new();
let res: ReqwestResponse = match client
.post(&format!("{}/completion", llm_url))
.json(&req)
.send()
.await
{
Ok(res) => res,
Err(e) => {
return Err(LlmError::RequestFailed {
error: format!("{}", e),
});
}
};
let llm_response = match res.json::<LlmResponse>().await {
Ok(response) => response,
Err(e) => {
return Err(LlmError::DeserializationToLlmResponseFailed {
error: format!("{}", e),
});
}
};
let _ = _print_tx
.send(Printout {
verbosity: 0,
content: format!("llm: {:?}", llm_response.clone().content),
})
.await;
let message = KernelMessage {
id,
source: Address {
node: our,
process: ProcessId::new(Some("llm"), "sys", "uqbar"),
},
target,
rsvp: None,
message: Message::Response((
Response {
inherit: false,
ipc: serde_json::to_vec::<Result<LlmResponse, LlmError>>(&Ok(llm_response))
.unwrap(),
metadata: None,
},
None,
)),
payload: None,
signed_capabilities: None,
};
send_to_loop.send(message).await.unwrap();
Ok(())
}
//
// helpers
//
fn make_error_message(
our_name: String,
id: u64,
source: Address,
error: LlmError,
) -> KernelMessage {
KernelMessage {
id,
source: source.clone(),
target: Address {
node: our_name.clone(),
process: source.process.clone(),
},
rsvp: None,
message: Message::Response((
Response {
inherit: false,
ipc: serde_json::to_vec::<Result<HttpClientResponse, LlmError>>(&Err(error))
.unwrap(),
metadata: None,
},
None,
)),
payload: None,
signed_capabilities: None,
}
}

View File

@ -1,114 +0,0 @@
use serde::{Deserialize, Serialize};
use thiserror::Error;
#[derive(Debug, Serialize, Deserialize)]
pub struct LlmPrompt {
prompt: String, // TODO can be a string or an array of strings
temperature: Option<f64>,
top_k: Option<usize>,
top_p: Option<f64>,
n_predict: Option<isize>, // isize to accommodate -1
n_keep: Option<isize>, // isize to accommodate -1
stream: Option<bool>,
stop: Option<Vec<String>>,
tfs_z: Option<f64>,
typical_p: Option<f64>,
repeat_penalty: Option<f64>,
repeat_last_n: Option<isize>, // isize to accommodate -1
penalize_nl: Option<bool>,
presence_penalty: Option<f64>,
frequency_penalty: Option<f64>,
mirostat: Option<u8>, // u8 as it's 0, 1, or 2
mirostat_tau: Option<f64>,
mirostat_eta: Option<f64>,
grammar: Option<String>,
seed: Option<isize>, // isize to accommodate -1
ignore_eos: Option<bool>,
logit_bias: Option<Vec<(usize, f64)>>,
n_probs: Option<usize>,
image_data: Option<Vec<ImageData>>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct ImageData {
data: String, // Base64 string
id: usize,
}
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct LlmResponse {
pub content: String,
pub generation_settings: GenerationSettings,
pub model: String,
pub prompt: String,
pub slot_id: u64,
pub stop: bool,
pub stopped_eos: bool,
pub stopped_limit: bool,
pub stopped_word: bool,
pub stopping_word: String,
pub timings: Timings,
pub tokens_cached: u64,
pub tokens_evaluated: u64,
pub tokens_predicted: u64,
pub truncated: bool,
}
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct GenerationSettings {
pub frequency_penalty: f64,
pub grammar: String,
pub ignore_eos: bool,
pub logit_bias: Vec<serde_json::Value>, // This should be changed to the appropriate type
pub mirostat: u64,
pub mirostat_eta: f64,
pub mirostat_tau: f64,
pub model: String,
pub n_ctx: u64,
pub n_keep: u64,
pub n_predict: u64,
pub n_probs: u64,
pub penalize_nl: bool,
pub presence_penalty: f64,
pub repeat_last_n: u64,
pub repeat_penalty: f64,
pub seed: u64,
pub stop: Vec<serde_json::Value>, // This should be changed to the appropriate type
pub stream: bool,
pub temp: f64,
pub tfs_z: f64,
pub top_k: u64,
pub top_p: f64,
pub typical_p: f64,
}
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct Timings {
pub predicted_ms: f64,
pub predicted_n: u64,
pub predicted_per_second: f64,
pub predicted_per_token_ms: f64,
pub prompt_ms: f64,
pub prompt_n: u64,
pub prompt_per_second: f64,
pub prompt_per_token_ms: f64,
}
#[derive(Error, Debug, Serialize, Deserialize)]
pub enum LlmError {
#[error("llm: rsvp is None but message is expecting response")]
BadRsvp,
#[error("llm: no json in request")]
NoJson,
#[error(
"llm: JSON payload could not be parsed to LlmPrompt: {error}. Got {:?}.",
json
)]
BadJson { json: String, error: String },
#[error("llm: http method not supported: {:?}", method)]
BadMethod { method: String },
#[error("llm: failed to execute request {:?}", error)]
RequestFailed { error: String },
#[error("llm: failed to deserialize response {:?}", error)]
DeserializationToLlmResponseFailed { error: String },
}

View File

@ -23,10 +23,6 @@ mod timer;
mod types; mod types;
mod vfs; mod vfs;
// extensions
#[cfg(feature = "llm")]
mod llm;
const EVENT_LOOP_CHANNEL_CAPACITY: usize = 10_000; const EVENT_LOOP_CHANNEL_CAPACITY: usize = 10_000;
const EVENT_LOOP_DEBUG_CHANNEL_CAPACITY: usize = 50; const EVENT_LOOP_DEBUG_CHANNEL_CAPACITY: usize = 50;
const TERMINAL_CHANNEL_CAPACITY: usize = 32; const TERMINAL_CHANNEL_CAPACITY: usize = 32;
@ -36,8 +32,6 @@ const HTTP_CLIENT_CHANNEL_CAPACITY: usize = 32;
const ETH_RPC_CHANNEL_CAPACITY: usize = 32; const ETH_RPC_CHANNEL_CAPACITY: usize = 32;
const VFS_CHANNEL_CAPACITY: usize = 1_000; const VFS_CHANNEL_CAPACITY: usize = 1_000;
const CAP_CHANNEL_CAPACITY: usize = 1_000; const CAP_CHANNEL_CAPACITY: usize = 1_000;
#[cfg(feature = "llm")]
const LLM_CHANNEL_CAPACITY: usize = 32;
const VERSION: &str = env!("CARGO_PKG_VERSION"); const VERSION: &str = env!("CARGO_PKG_VERSION");
@ -51,7 +45,7 @@ async fn serve_register_fe(
our_ip: String, our_ip: String,
http_server_port: u16, http_server_port: u16,
rpc_url: String, rpc_url: String,
) -> (Identity, Keyfile) { ) -> (Identity, Vec<u8>, Keyfile) {
// check if we have keys saved on disk, encrypted // check if we have keys saved on disk, encrypted
// if so, prompt user for "password" to decrypt with // if so, prompt user for "password" to decrypt with
@ -65,10 +59,9 @@ async fn serve_register_fe(
// that updates their PKI info on-chain. // that updates their PKI info on-chain.
let (kill_tx, kill_rx) = oneshot::channel::<bool>(); let (kill_tx, kill_rx) = oneshot::channel::<bool>();
let disk_keyfile = match fs::read(format!("{}/.keys", home_directory_path)).await { let disk_keyfile: Option<Vec<u8>> = fs::read(format!("{}/.keys", home_directory_path))
Ok(keyfile) => keyfile, .await
Err(_) => Vec::new(), .ok();
};
let (tx, mut rx) = mpsc::channel::<(Identity, Keyfile, Vec<u8>)>(1); let (tx, mut rx) = mpsc::channel::<(Identity, Keyfile, Vec<u8>)>(1);
let (our, decoded_keyfile, encoded_keyfile) = tokio::select! { let (our, decoded_keyfile, encoded_keyfile) = tokio::select! {
@ -80,20 +73,16 @@ async fn serve_register_fe(
} }
}; };
println!( fs::write(
"saving encrypted networking keys to {}/.keys", format!("{}/.keys", home_directory_path),
home_directory_path encoded_keyfile.clone(),
); )
.await
fs::write(format!("{}/.keys", home_directory_path), encoded_keyfile) .unwrap();
.await
.unwrap();
println!("registration complete!");
let _ = kill_tx.send(true); let _ = kill_tx.send(true);
(our, decoded_keyfile) (our, encoded_keyfile, decoded_keyfile)
} }
#[tokio::main] #[tokio::main]
@ -123,9 +112,6 @@ async fn main() {
.value_parser(value_parser!(u16)), .value_parser(value_parser!(u16)),
); );
#[cfg(feature = "llm")]
let app = app.arg(arg!(--llm <LLM_URL> "LLM endpoint"));
let matches = app.get_matches(); let matches = app.get_matches();
let home_directory_path = matches.get_one::<String>("home").unwrap(); let home_directory_path = matches.get_one::<String>("home").unwrap();
@ -145,9 +131,6 @@ async fn main() {
matches.get_one::<String>("fake-node-name"), matches.get_one::<String>("fake-node-name"),
); );
#[cfg(feature = "llm")]
let llm_url = matches.get_one::<String>("llm").unwrap();
if let Err(e) = fs::create_dir_all(home_directory_path).await { if let Err(e) = fs::create_dir_all(home_directory_path).await {
panic!("failed to create home directory: {:?}", e); panic!("failed to create home directory: {:?}", e);
} }
@ -188,10 +171,6 @@ async fn main() {
// terminal receives prints via this channel, all other modules send prints // terminal receives prints via this channel, all other modules send prints
let (print_sender, print_receiver): (PrintSender, PrintReceiver) = let (print_sender, print_receiver): (PrintSender, PrintReceiver) =
mpsc::channel(TERMINAL_CHANNEL_CAPACITY); mpsc::channel(TERMINAL_CHANNEL_CAPACITY);
// optional llm extension
#[cfg(feature = "llm")]
let (llm_sender, llm_receiver): (MessageSender, MessageReceiver) =
mpsc::channel(LLM_CHANNEL_CAPACITY);
println!("finding public IP address..."); println!("finding public IP address...");
let our_ip: std::net::Ipv4Addr = { let our_ip: std::net::Ipv4Addr = {
@ -207,13 +186,12 @@ async fn main() {
}; };
let http_server_port = http::utils::find_open_port(port).await.unwrap(); let http_server_port = http::utils::find_open_port(port).await.unwrap();
println!("runtime bound port {}\r", http_server_port);
println!( println!(
"login or register at http://localhost:{}\r", "login or register at http://localhost:{}\r",
http_server_port http_server_port
); );
#[cfg(not(feature = "simulation-mode"))] #[cfg(not(feature = "simulation-mode"))]
let (our, decoded_keyfile) = serve_register_fe( let (our, encoded_keyfile, decoded_keyfile) = serve_register_fe(
&home_directory_path, &home_directory_path,
our_ip.to_string(), our_ip.to_string(),
http_server_port.clone(), http_server_port.clone(),
@ -221,7 +199,7 @@ async fn main() {
) )
.await; .await;
#[cfg(feature = "simulation-mode")] #[cfg(feature = "simulation-mode")]
let (our, decoded_keyfile) = match fake_node_name { let (our, encoded_keyfile, decoded_keyfile) = match fake_node_name {
None => { None => {
match password { match password {
None => match rpc_url { None => match rpc_url {
@ -240,7 +218,7 @@ async fn main() {
match fs::read(format!("{}/.keys", home_directory_path)).await { match fs::read(format!("{}/.keys", home_directory_path)).await {
Err(e) => panic!("could not read keyfile: {}", e), Err(e) => panic!("could not read keyfile: {}", e),
Ok(keyfile) => { Ok(keyfile) => {
match keygen::decode_keyfile(keyfile, &password) { match keygen::decode_keyfile(&keyfile, &password) {
Err(e) => panic!("could not decode keyfile: {}", e), Err(e) => panic!("could not decode keyfile: {}", e),
Ok(decoded_keyfile) => { Ok(decoded_keyfile) => {
let our = Identity { let our = Identity {
@ -257,7 +235,7 @@ async fn main() {
ws_routing: None, // TODO ws_routing: None, // TODO
allowed_routers: decoded_keyfile.routers.clone(), allowed_routers: decoded_keyfile.routers.clone(),
}; };
(our, decoded_keyfile) (our, keyfile, decoded_keyfile)
} }
} }
} }
@ -298,16 +276,19 @@ async fn main() {
password, password,
name.clone(), name.clone(),
decoded_keyfile.routers.clone(), decoded_keyfile.routers.clone(),
networking_keypair, networking_keypair.as_ref(),
decoded_keyfile.jwt_secret_bytes.clone(), decoded_keyfile.jwt_secret_bytes.clone(),
decoded_keyfile.file_key.clone(), decoded_keyfile.file_key.clone(),
); );
fs::write(format!("{}/.keys", home_directory_path), encoded_keyfile) fs::write(
.await format!("{}/.keys", home_directory_path),
.unwrap(); encoded_keyfile.clone(),
)
.await
.unwrap();
(our, decoded_keyfile) (our, encoded_keyfile, decoded_keyfile)
} }
}; };
@ -415,6 +396,7 @@ async fn main() {
tasks.spawn(http::server::http_server( tasks.spawn(http::server::http_server(
our.name.clone(), our.name.clone(),
http_server_port, http_server_port,
encoded_keyfile,
decoded_keyfile.jwt_secret_bytes.clone(), decoded_keyfile.jwt_secret_bytes.clone(),
http_server_receiver, http_server_receiver,
kernel_message_sender.clone(), kernel_message_sender.clone(),
@ -448,16 +430,6 @@ async fn main() {
caps_oracle_sender.clone(), caps_oracle_sender.clone(),
home_directory_path.clone(), home_directory_path.clone(),
)); ));
#[cfg(feature = "llm")]
{
tasks.spawn(llm::llm(
our.name.clone(),
kernel_message_sender.clone(),
llm_receiver,
llm_url.to_string(),
print_sender.clone(),
));
}
// if a runtime task exits, try to recover it, // if a runtime task exits, try to recover it,
// unless it was terminal signaling a quit // unless it was terminal signaling a quit
let quit_msg: String = tokio::select! { let quit_msg: String = tokio::select! {

View File

@ -65,7 +65,7 @@ pub async fn maintain_connection(
if km.source.node != peer_name { if km.source.node != peer_name {
let _ = print_tx.send(Printout { let _ = print_tx.send(Printout {
verbosity: 0, verbosity: 0,
content: format!("net: got message with spoofed source from {peer_name}") content: format!("net: got message with spoofed source from {peer_name}!")
}).await; }).await;
break break
} else { } else {
@ -136,7 +136,9 @@ pub async fn maintain_passthrough(mut conn: PassthroughConnection) {
maybe_recv = conn.read_stream_1.next() => { maybe_recv = conn.read_stream_1.next() => {
match maybe_recv { match maybe_recv {
Some(Ok(msg)) => { Some(Ok(msg)) => {
conn.write_stream_2.send(msg).await.expect("net error: fatal: kernel died"); let Ok(()) = conn.write_stream_2.send(msg).await else {
break
};
last_message = std::time::Instant::now(); last_message = std::time::Instant::now();
} }
_ => break, _ => break,
@ -145,7 +147,9 @@ pub async fn maintain_passthrough(mut conn: PassthroughConnection) {
maybe_recv = conn.read_stream_2.next() => { maybe_recv = conn.read_stream_2.next() => {
match maybe_recv { match maybe_recv {
Some(Ok(msg)) => { Some(Ok(msg)) => {
conn.write_stream_1.send(msg).await.expect("net error: fatal: kernel died"); let Ok(()) = conn.write_stream_1.send(msg).await else {
break
};
last_message = std::time::Instant::now(); last_message = std::time::Instant::now();
} }
_ => break, _ => break,

View File

@ -1,15 +1,13 @@
use aes_gcm::aead::KeyInit; use aes_gcm::aead::KeyInit;
use ethers::prelude::{abigen, namehash, Address as EthAddress, Provider, U256}; use ethers::prelude::{abigen, namehash, Address as EthAddress, Provider, U256};
use ethers_providers::Ws; use ethers_providers::Ws;
use hmac::Hmac; use hmac::Hmac;
use jwt::SignWithKey; use jwt::SignWithKey;
use ring::pkcs8::Document;
use ring::rand::SystemRandom; use ring::rand::SystemRandom;
use ring::signature; use ring::signature;
use ring::signature::KeyPair; use ring::signature::KeyPair;
use sha2::Sha256; use sha2::Sha256;
use std::sync::{Arc, Mutex}; use std::sync::Arc;
use tokio::sync::{mpsc, oneshot}; use tokio::sync::{mpsc, oneshot};
use warp::{ use warp::{
http::{ http::{
@ -77,14 +75,14 @@ fn _hex_string_to_u8_array(hex_str: &str) -> Result<[u8; 32], &'static str> {
Ok(bytes) Ok(bytes)
} }
pub fn generate_jwt(jwt_secret_bytes: &[u8], username: String) -> Option<String> { pub fn generate_jwt(jwt_secret_bytes: &[u8], username: &str) -> Option<String> {
let jwt_secret: Hmac<Sha256> = match Hmac::new_from_slice(jwt_secret_bytes) { let jwt_secret: Hmac<Sha256> = match Hmac::new_from_slice(jwt_secret_bytes) {
Ok(secret) => secret, Ok(secret) => secret,
Err(_) => return None, Err(_) => return None,
}; };
let claims = crate::http::types::JwtClaims { let claims = crate::http::types::JwtClaims {
username: username.clone(), username: username.to_string(),
expiration: 0, expiration: 0,
}; };
@ -101,16 +99,34 @@ pub async fn register(
ip: String, ip: String,
port: u16, port: u16,
rpc_url: String, rpc_url: String,
keyfile: Vec<u8>, keyfile: Option<Vec<u8>>,
) { ) {
let our_temp_arc = Arc::new(Mutex::new(None)); // Networking info is generated and passed to the UI, but not used until confirmed // Networking info is generated and passed to the UI, but not used until confirmed
let our_ws_info = our_temp_arc.clone(); let (public_key, serialized_networking_keypair) = keygen::generate_networking_key();
let net_keypair = Arc::new(serialized_networking_keypair.as_ref().to_vec());
let tx = Arc::new(tx);
let net_keypair_arc = Arc::new(Mutex::new(None)); // TODO: if IP is localhost, don't allow registration as direct
let net_keypair_ws_info = net_keypair_arc.clone(); let ws_port = crate::http::utils::find_open_port(9000).await.unwrap();
let keyfile_arc = Arc::new(Mutex::new(Some(keyfile))); // This is a temporary identity, passed to the UI. If it is confirmed through a /boot or /confirm-change-network-keys, then it will be used to replace the current identity
let keyfile_vet = keyfile_arc.clone(); let our_temp_id = Arc::new(Identity {
networking_key: format!("0x{}", public_key),
name: "".to_string(),
ws_routing: Some((ip.clone(), ws_port)),
allowed_routers: vec![
"uqbar-router-1.uq".into(), // "0x8d9e54427c50660c6d4802f63edca86a9ca5fd6a78070c4635950e9d149ed441".into(),
"uqbar-router-2.uq".into(), // "0x06d331ed65843ecf0860c73292005d8103af20820546b2f8f9007d01f60595b1".into(),
"uqbar-router-3.uq".into(), // "0xe6ab611eb62e8aee0460295667f8179cda4315982717db4b0b3da6022deecac1".into(),
],
});
let keyfile = warp::any().map(move || keyfile.clone());
let our_temp_id = warp::any().map(move || our_temp_id.clone());
let net_keypair = warp::any().map(move || net_keypair.clone());
let tx = warp::any().map(move || tx.clone());
let ip = warp::any().map(move || ip.clone());
let rpc_url = warp::any().map(move || rpc_url.clone());
let static_files = warp::path("static").and(warp::fs::dir("./src/register-ui/build/static/")); let static_files = warp::path("static").and(warp::fs::dir("./src/register-ui/build/static/"));
@ -118,73 +134,60 @@ pub async fn register(
.and(warp::get()) .and(warp::get())
.and(warp::fs::file("./src/register-ui/build/index.html")); .and(warp::fs::file("./src/register-ui/build/index.html"));
let keyfile_info_copy = keyfile_arc.clone();
let boot_tx = tx.clone();
let boot_our_arc = our_temp_arc.clone();
let boot_net_keypair_arc = net_keypair_arc.clone();
let import_tx = tx.clone();
let import_ip = ip.clone();
let import_rpc_url = rpc_url.clone();
let login_tx = tx.clone();
let login_keyfile_arc = keyfile_arc.clone();
let generate_keys_ip = ip.clone();
let api = warp::path("info") let api = warp::path("info")
.and( .and(
warp::get() warp::get()
.and(warp::any().map(move || keyfile_info_copy.clone())) .and(keyfile.clone())
.and_then(get_unencrypted_info), .and_then(get_unencrypted_info),
) )
.or(warp::path("generate-networking-info").and( .or(warp::path("generate-networking-info").and(
warp::post() warp::post()
.and(warp::any().map(move || generate_keys_ip.clone())) .and(our_temp_id.clone())
.and(warp::any().map(move || our_ws_info.clone()))
.and(warp::any().map(move || net_keypair_ws_info.clone()))
.and_then(generate_networking_info), .and_then(generate_networking_info),
)) ))
.or(warp::path("vet-keyfile").and( .or(warp::path("vet-keyfile").and(
warp::post() warp::post()
.and(warp::body::content_length_limit(1024 * 16)) .and(warp::body::content_length_limit(1024 * 16))
.and(warp::body::json()) .and(warp::body::json())
.and(warp::any().map(move || keyfile_vet.clone())) .and(keyfile.clone())
.and_then(handle_keyfile_vet), .and_then(handle_keyfile_vet),
)) ))
.or(warp::path("boot").and( .or(warp::path("boot").and(
warp::post() warp::post()
.and(warp::body::content_length_limit(1024 * 16)) .and(warp::body::content_length_limit(1024 * 16))
.and(warp::body::json()) .and(warp::body::json())
.and(warp::any().map(move || boot_tx.clone())) .and(tx.clone())
.and(warp::any().map(move || boot_our_arc.lock().unwrap().take().unwrap())) .and(our_temp_id.clone())
.and(warp::any().map(move || boot_net_keypair_arc.lock().unwrap().take().unwrap())) .and(net_keypair.clone())
.and_then(handle_boot), .and_then(handle_boot),
)) ))
.or(warp::path("import-keyfile").and( .or(warp::path("import-keyfile").and(
warp::post() warp::post()
.and(warp::body::content_length_limit(1024 * 16)) .and(warp::body::content_length_limit(1024 * 16))
.and(warp::body::json()) .and(warp::body::json())
.and(warp::any().map(move || import_ip.clone())) .and(ip.clone())
.and(warp::any().map(move || import_rpc_url.clone())) .and(rpc_url.clone())
.and(warp::any().map(move || import_tx.clone())) .and(tx.clone())
.and_then(handle_import_keyfile), .and_then(handle_import_keyfile),
)) ))
.or(warp::path("login").and( .or(warp::path("login").and(
warp::post() warp::post()
.and(warp::body::content_length_limit(1024 * 16)) .and(warp::body::content_length_limit(1024 * 16))
.and(warp::body::json()) .and(warp::body::json())
.and(warp::any().map(move || ip.clone())) .and(ip)
.and(warp::any().map(move || rpc_url.clone())) .and(rpc_url)
.and(warp::any().map(move || login_tx.clone())) .and(tx.clone())
.and(warp::any().map(move || login_keyfile_arc.lock().unwrap().take().unwrap())) .and(keyfile.clone())
.and_then(handle_login), .and_then(handle_login),
)) ))
.or(warp::path("confirm-change-network-keys").and( .or(warp::path("confirm-change-network-keys").and(
warp::post() warp::post()
.and(warp::body::content_length_limit(1024 * 16)) .and(warp::body::content_length_limit(1024 * 16))
.and(warp::body::json()) .and(warp::body::json())
.and(warp::any().map(move || tx.clone())) .and(tx)
.and(warp::any().map(move || our_temp_arc.lock().unwrap().take().unwrap())) .and(our_temp_id)
.and(warp::any().map(move || net_keypair_arc.lock().unwrap().take().unwrap())) .and(net_keypair)
.and(warp::any().map(move || keyfile_arc.lock().unwrap().take().unwrap())) .and(keyfile)
.and_then(confirm_change_network_keys), .and_then(confirm_change_network_keys),
)); ));
@ -208,101 +211,72 @@ pub async fn register(
.await; .await;
} }
async fn get_unencrypted_info( async fn get_unencrypted_info(keyfile: Option<Vec<u8>>) -> Result<impl Reply, Rejection> {
keyfile_arc: Arc<Mutex<Option<Vec<u8>>>>,
) -> Result<impl Reply, Rejection> {
let (name, allowed_routers) = { let (name, allowed_routers) = {
match keyfile_arc.lock().unwrap().clone() { match keyfile {
Some(encoded_keyfile) => match keygen::get_username_and_routers(encoded_keyfile) { Some(encoded_keyfile) => match keygen::get_username_and_routers(&encoded_keyfile) {
Ok(k) => k, Ok(k) => k,
Err(_) => { Err(_) => {
return Ok(warp::reply::with_status( return Ok(warp::reply::with_status(
warp::reply::json(&"Failed to decode keyfile".to_string()), warp::reply::json(&"Incorrect password"),
StatusCode::INTERNAL_SERVER_ERROR, StatusCode::UNAUTHORIZED,
) )
.into_response()) .into_response())
} }
}, },
None => { None => {
return Ok(warp::reply::with_status( return Ok(warp::reply::with_status(
warp::reply::json(&"Keyfile not present".to_string()), warp::reply::json(&"Keyfile not present"),
StatusCode::NOT_FOUND, StatusCode::NOT_FOUND,
) )
.into_response()) .into_response())
} }
} }
}; };
Ok(warp::reply::with_status(
let our = UnencryptedIdentity { Ok(warp::reply::json(&UnencryptedIdentity {
name, name,
allowed_routers, allowed_routers,
}; })),
StatusCode::OK,
Ok(warp::reply::with_status(Ok(warp::reply::json(&our)), StatusCode::OK).into_response()) )
.into_response())
} }
async fn generate_networking_info( async fn generate_networking_info(our_temp_id: Arc<Identity>) -> Result<impl Reply, Rejection> {
ip: String, Ok(warp::reply::json(our_temp_id.as_ref()))
our_temp_arc: Arc<Mutex<Option<Identity>>>,
networking_keypair_arc: Arc<Mutex<Option<Document>>>,
) -> Result<impl Reply, Rejection> {
let (public_key, serialized_networking_keypair) = keygen::generate_networking_key();
*networking_keypair_arc.lock().unwrap() = Some(serialized_networking_keypair);
// TODO: if IP is localhost, don't allow registration as direct
let ws_port = crate::http::utils::find_open_port(9000).await.unwrap();
// This is a temporary identity, passed to the UI. If it is confirmed through a /boot or /confirm-change-network-keys, then it will be used to replace the current identity
let our_temp = Identity {
networking_key: format!("0x{}", public_key),
name: "".to_string(),
ws_routing: Some((ip, ws_port)),
allowed_routers: vec![
"uqbar-router-1.uq".into(), // "0x8d9e54427c50660c6d4802f63edca86a9ca5fd6a78070c4635950e9d149ed441".into(),
"uqbar-router-2.uq".into(), // "0x06d331ed65843ecf0860c73292005d8103af20820546b2f8f9007d01f60595b1".into(),
"uqbar-router-3.uq".into(), // "0xe6ab611eb62e8aee0460295667f8179cda4315982717db4b0b3da6022deecac1".into(),
],
};
*our_temp_arc.lock().unwrap() = Some(our_temp.clone());
Ok(warp::reply::json(&our_temp))
} }
async fn handle_keyfile_vet( async fn handle_keyfile_vet(
payload: KeyfileVet, payload: KeyfileVet,
keyfile_arc: Arc<Mutex<Option<Vec<u8>>>>, keyfile: Option<Vec<u8>>,
) -> Result<impl Reply, Rejection> { ) -> Result<impl Reply, Rejection> {
let encoded_keyfile = match payload.keyfile.is_empty() { let encoded_keyfile = match payload.keyfile.is_empty() {
true => keyfile_arc.lock().unwrap().clone().unwrap(), true => keyfile.ok_or(warp::reject())?,
false => base64::decode(payload.keyfile).unwrap(), false => base64::decode(payload.keyfile).map_err(|_| warp::reject())?,
}; };
let decoded_keyfile = match keygen::decode_keyfile(encoded_keyfile, &payload.password) { let decoded_keyfile =
Ok(k) => k, keygen::decode_keyfile(&encoded_keyfile, &payload.password).map_err(|_| warp::reject())?;
Err(_) => return Err(warp::reject()),
};
let keyfile_vetted = KeyfileVetted { Ok(warp::reply::json(&KeyfileVetted {
username: decoded_keyfile.username, username: decoded_keyfile.username,
networking_key: format!( networking_key: format!(
"0x{}", "0x{}",
hex::encode(decoded_keyfile.networking_keypair.public_key().as_ref()) hex::encode(decoded_keyfile.networking_keypair.public_key().as_ref())
), ),
routers: decoded_keyfile.routers, routers: decoded_keyfile.routers,
}; }))
Ok(warp::reply::json(&keyfile_vetted))
} }
async fn handle_boot( async fn handle_boot(
info: BootInfo, info: BootInfo,
sender: RegistrationSender, sender: Arc<RegistrationSender>,
mut our: Identity, our: Arc<Identity>,
networking_keypair: Document, networking_keypair: Arc<Vec<u8>>,
) -> Result<impl Reply, Rejection> { ) -> Result<impl Reply, Rejection> {
let mut our = our.as_ref().clone();
our.name = info.username; our.name = info.username;
if info.direct { if info.direct {
our.allowed_routers = vec![]; our.allowed_routers = vec![];
} else { } else {
@ -326,35 +300,26 @@ async fn handle_boot(
info.password, info.password,
decoded_keyfile.username.clone(), decoded_keyfile.username.clone(),
decoded_keyfile.routers.clone(), decoded_keyfile.routers.clone(),
networking_keypair, networking_keypair.as_ref(),
decoded_keyfile.jwt_secret_bytes.clone(), decoded_keyfile.jwt_secret_bytes.clone(),
decoded_keyfile.file_key.clone(), decoded_keyfile.file_key.clone(),
); );
let encoded_keyfile_str = base64::encode(encoded_keyfile.clone()); success_response(sender, our, decoded_keyfile, encoded_keyfile).await
success_response(
sender,
our,
decoded_keyfile,
encoded_keyfile,
encoded_keyfile_str,
)
.await
} }
async fn handle_import_keyfile( async fn handle_import_keyfile(
info: ImportKeyfileInfo, info: ImportKeyfileInfo,
ip: String, ip: String,
_rpc_url: String, _rpc_url: String,
sender: RegistrationSender, sender: Arc<RegistrationSender>,
) -> Result<impl Reply, Rejection> { ) -> Result<impl Reply, Rejection> {
// if keyfile was not present in node and is present from user upload // if keyfile was not present in node and is present from user upload
let encoded_keyfile = match base64::decode(info.keyfile.clone()) { let encoded_keyfile = match base64::decode(info.keyfile.clone()) {
Ok(k) => k, Ok(k) => k,
Err(_) => { Err(_) => {
return Ok(warp::reply::with_status( return Ok(warp::reply::with_status(
warp::reply::json(&"Keyfile not valid base64".to_string()), warp::reply::json(&"Keyfile not valid base64"),
StatusCode::BAD_REQUEST, StatusCode::BAD_REQUEST,
) )
.into_response()) .into_response())
@ -363,39 +328,38 @@ async fn handle_import_keyfile(
let Some(ws_port) = crate::http::utils::find_open_port(9000).await else { let Some(ws_port) = crate::http::utils::find_open_port(9000).await else {
return Ok(warp::reply::with_status( return Ok(warp::reply::with_status(
warp::reply::json(&"Unable to find free port".to_string()), warp::reply::json(&"Unable to find free port"),
StatusCode::INTERNAL_SERVER_ERROR, StatusCode::INTERNAL_SERVER_ERROR,
) )
.into_response()); .into_response());
}; };
let (decoded_keyfile, our) = let (decoded_keyfile, our) = match keygen::decode_keyfile(&encoded_keyfile, &info.password) {
match keygen::decode_keyfile(encoded_keyfile.clone(), &info.password) { Ok(k) => {
Ok(k) => { let our = Identity {
let our = Identity { name: k.username.clone(),
name: k.username.clone(), networking_key: format!(
networking_key: format!( "0x{}",
"0x{}", hex::encode(k.networking_keypair.public_key().as_ref())
hex::encode(k.networking_keypair.public_key().as_ref()) ),
), ws_routing: if k.routers.is_empty() {
ws_routing: if k.routers.is_empty() { Some((ip, ws_port))
Some((ip, ws_port)) } else {
} else { None
None },
}, allowed_routers: k.routers.clone(),
allowed_routers: k.routers.clone(), };
};
(k, our) (k, our)
} }
Err(_) => { Err(_) => {
return Ok(warp::reply::with_status( return Ok(warp::reply::with_status(
warp::reply::json(&"Failed to decode keyfile".to_string()), warp::reply::json(&"Incorrect Password".to_string()),
StatusCode::INTERNAL_SERVER_ERROR, StatusCode::UNAUTHORIZED,
) )
.into_response()) .into_response())
} }
}; };
// if !networking_info_valid(rpc_url, ip, ws_port, &our).await { // if !networking_info_valid(rpc_url, ip, ws_port, &our).await {
// return Ok(warp::reply::with_status( // return Ok(warp::reply::with_status(
@ -405,114 +369,89 @@ async fn handle_import_keyfile(
// .into_response()); // .into_response());
// } // }
let encoded_keyfile_str = info.keyfile.clone(); success_response(sender, our, decoded_keyfile, encoded_keyfile).await
success_response(
sender,
our,
decoded_keyfile,
encoded_keyfile,
encoded_keyfile_str,
)
.await
} }
async fn handle_login( async fn handle_login(
info: LoginInfo, info: LoginInfo,
ip: String, ip: String,
_rpc_url: String, _rpc_url: String,
sender: RegistrationSender, sender: Arc<RegistrationSender>,
encoded_keyfile: Vec<u8>, encoded_keyfile: Option<Vec<u8>>,
) -> Result<impl Reply, Rejection> { ) -> Result<impl Reply, Rejection> {
if encoded_keyfile.is_empty() { if encoded_keyfile.is_none() {
return Ok(warp::reply::with_status( return Ok(warp::reply::with_status(
warp::reply::json(&"Keyfile not present".to_string()), warp::reply::json(&"Keyfile not present"),
StatusCode::NOT_FOUND, StatusCode::NOT_FOUND,
) )
.into_response()); .into_response());
} }
let encoded_keyfile = encoded_keyfile.unwrap();
let Some(ws_port) = crate::http::utils::find_open_port(9000).await else { let Some(ws_port) = crate::http::utils::find_open_port(9000).await else {
return Ok(warp::reply::with_status( return Ok(warp::reply::with_status(
warp::reply::json(&"Unable to find free port".to_string()), warp::reply::json(&"Unable to find free port"),
StatusCode::INTERNAL_SERVER_ERROR, StatusCode::INTERNAL_SERVER_ERROR,
) )
.into_response()); .into_response());
}; };
let (decoded_keyfile, our) = let (decoded_keyfile, our) = match keygen::decode_keyfile(&encoded_keyfile, &info.password) {
match keygen::decode_keyfile(encoded_keyfile.clone(), &info.password) { Ok(k) => {
Ok(k) => { let our = Identity {
let our = Identity { name: k.username.clone(),
name: k.username.clone(), networking_key: format!(
networking_key: format!( "0x{}",
"0x{}", hex::encode(k.networking_keypair.public_key().as_ref())
hex::encode(k.networking_keypair.public_key().as_ref()) ),
), ws_routing: if k.routers.is_empty() {
ws_routing: if k.routers.is_empty() { Some((ip, ws_port))
Some((ip, ws_port)) } else {
} else { None
None },
}, allowed_routers: k.routers.clone(),
allowed_routers: k.routers.clone(), };
};
(k, our) (k, our)
} }
Err(_) => { Err(_) => {
return Ok(warp::reply::with_status( return Ok(warp::reply::with_status(
warp::reply::json(&"Failed to decode keyfile".to_string()), warp::reply::json(&"Incorrect Password"),
StatusCode::INTERNAL_SERVER_ERROR, StatusCode::UNAUTHORIZED,
) )
.into_response()) .into_response())
} }
}; };
// if !networking_info_valid(rpc_url, ip, ws_port, &our).await { success_response(sender, our, decoded_keyfile, encoded_keyfile).await
// return Ok(warp::reply::with_status(
// warp::reply::json(&"Networking info invalid".to_string()),
// StatusCode::UNAUTHORIZED,
// )
// .into_response());
// }
let encoded_keyfile_str = base64::encode(encoded_keyfile.clone());
success_response(
sender,
our,
decoded_keyfile,
encoded_keyfile,
encoded_keyfile_str,
)
.await
} }
async fn confirm_change_network_keys( async fn confirm_change_network_keys(
info: LoginAndResetInfo, info: LoginAndResetInfo,
sender: RegistrationSender, sender: Arc<RegistrationSender>,
mut our: Identity, // the arc of our temporary identity our: Arc<Identity>,
networking_keypair: Document, networking_keypair: Arc<Vec<u8>>,
encoded_keyfile: Vec<u8>, encoded_keyfile: Option<Vec<u8>>,
) -> Result<impl Reply, Rejection> { ) -> Result<impl Reply, Rejection> {
if encoded_keyfile.is_empty() { if encoded_keyfile.is_none() {
return Ok(warp::reply::with_status( return Ok(warp::reply::with_status(
warp::reply::json(&"Keyfile not present".to_string()), warp::reply::json(&"Keyfile not present"),
StatusCode::NOT_FOUND, StatusCode::NOT_FOUND,
) )
.into_response()); .into_response());
} }
let encoded_keyfile = encoded_keyfile.unwrap();
let mut our = our.as_ref().clone();
// Get our name from our current keyfile // Get our name from our current keyfile
let old_decoded_keyfile = match keygen::decode_keyfile(encoded_keyfile.clone(), &info.password) let old_decoded_keyfile = match keygen::decode_keyfile(&encoded_keyfile, &info.password) {
{
Ok(k) => { Ok(k) => {
our.name = k.username.clone(); our.name = k.username.clone();
k k
} }
Err(_) => { Err(_) => {
return Ok(warp::reply::with_status( return Ok(warp::reply::with_status(
warp::reply::json(&"Invalid password".to_string()), warp::reply::json(&"Invalid password"),
StatusCode::UNAUTHORIZED, StatusCode::UNAUTHORIZED,
) )
.into_response()); .into_response());
@ -539,35 +478,26 @@ async fn confirm_change_network_keys(
info.password, info.password,
decoded_keyfile.username.clone(), decoded_keyfile.username.clone(),
decoded_keyfile.routers.clone(), decoded_keyfile.routers.clone(),
networking_keypair, networking_keypair.as_ref(),
decoded_keyfile.jwt_secret_bytes.clone(), decoded_keyfile.jwt_secret_bytes.clone(),
decoded_keyfile.file_key.clone(), decoded_keyfile.file_key.clone(),
); );
let encoded_keyfile_str = base64::encode(encoded_keyfile.clone()); success_response(sender, our.clone(), decoded_keyfile, encoded_keyfile).await
success_response(
sender,
our,
decoded_keyfile,
encoded_keyfile,
encoded_keyfile_str,
)
.await
} }
async fn success_response( async fn success_response(
sender: RegistrationSender, sender: Arc<RegistrationSender>,
our: Identity, our: Identity,
decoded_keyfile: Keyfile, decoded_keyfile: Keyfile,
encoded_keyfile: Vec<u8>, encoded_keyfile: Vec<u8>,
encoded_keyfile_str: String,
) -> Result<warp::reply::Response, Rejection> { ) -> Result<warp::reply::Response, Rejection> {
let token = match generate_jwt(&decoded_keyfile.jwt_secret_bytes, our.name.clone()) { let encoded_keyfile_str = base64::encode(&encoded_keyfile);
let token = match generate_jwt(&decoded_keyfile.jwt_secret_bytes, &our.name) {
Some(token) => token, Some(token) => token,
None => { None => {
return Ok(warp::reply::with_status( return Ok(warp::reply::with_status(
warp::reply::json(&"Failed to generate JWT".to_string()), warp::reply::json(&"Failed to generate JWT"),
StatusCode::SERVICE_UNAVAILABLE, StatusCode::SERVICE_UNAVAILABLE,
) )
.into_response()) .into_response())
@ -591,26 +521,13 @@ async fn success_response(
} }
Err(_) => { Err(_) => {
return Ok(warp::reply::with_status( return Ok(warp::reply::with_status(
warp::reply::json(&"Failed to generate Auth JWT".to_string()), warp::reply::json(&"Failed to generate Auth JWT"),
StatusCode::INTERNAL_SERVER_ERROR, StatusCode::INTERNAL_SERVER_ERROR,
) )
.into_response()) .into_response())
} }
} }
// match HeaderValue::from_str(&format!("uqbar-ws-auth_{}={};", &our.name, &token)) {
// Ok(v) => {
// headers.append(SET_COOKIE, v);
// },
// Err(_) => {
// return Ok(warp::reply::with_status(
// warp::reply::json(&"Failed to generate WS JWT".to_string()),
// StatusCode::INTERNAL_SERVER_ERROR,
// )
// .into_response())
// }
// }
Ok(response) Ok(response)
} }

View File

@ -146,7 +146,13 @@ pub async fn terminal(
stdout, stdout,
cursor::MoveTo(0, win_rows - 1), cursor::MoveTo(0, win_rows - 1),
terminal::Clear(ClearType::CurrentLine), terminal::Clear(ClearType::CurrentLine),
Print(format!("{} {}/{} {:02}:{:02} ", Print(format!("{}{} {}/{} {:02}:{:02} ",
match printout.verbosity {
0 => "",
1 => "1",
2 => "2",
_ => "3",
},
now.weekday(), now.weekday(),
now.month(), now.month(),
now.day(), now.day(),

Binary file not shown.