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/
uqbar
.vscode
.app-signing
.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"
[features]
llm = []
simulation-mode = []
[dependencies]
@ -63,7 +62,7 @@ rsa = "0.9"
rusoto_core = "0.48.0"
rusoto_s3 = "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_urlencoded = "0.7"
sha2 = "0.10"
@ -72,10 +71,10 @@ thiserror = "1.0"
tokio = { version = "1.28", features = ["fs", "macros", "rt-multi-thread", "sync"] }
tokio-tungstenite = "0.20.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"] }
warp = "0.3.5"
wasmtime = "14.0.4"
wasmtime-wasi = "14.0.4"
wasmtime = "15.0.1"
wasmtime-wasi = "15.0.1"
zip = "0.6"
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.
TODO: document feature flags here, `--llm` and `--simulation-mode`
TODO: document feature flags `--simulation-mode`
```bash
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:
```
!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 {"Download": {"package": {"package_name": "<pkg>", "publisher_node": "<node>"}, "install_from": "<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]]
name = "getrandom"
version = "0.2.10"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f"
dependencies = [
"cfg-if",
"libc",
@ -131,9 +131,9 @@ dependencies = [
[[package]]
name = "hashbrown"
version = "0.14.2"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156"
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
[[package]]
name = "heck"
@ -184,9 +184,9 @@ dependencies = [
[[package]]
name = "itoa"
version = "1.0.9"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
[[package]]
name = "leb128"
@ -196,9 +196,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67"
[[package]]
name = "libc"
version = "0.2.150"
version = "0.2.151"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4"
[[package]]
name = "log"
@ -220,9 +220,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "proc-macro2"
version = "1.0.69"
version = "1.0.70"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b"
dependencies = [
"unicode-ident",
]
@ -268,9 +268,9 @@ dependencies = [
[[package]]
name = "ryu"
version = "1.0.15"
version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
[[package]]
name = "semver"
@ -280,18 +280,18 @@ checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090"
[[package]]
name = "serde"
version = "1.0.191"
version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a834c4821019838224821468552240d4d95d14e751986442c816572d39a080c9"
checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.191"
version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46fa52d5646bce91b680189fe5b1c049d2ea38dabb4e2e7c8d00ca12cfbfbcfd"
checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
dependencies = [
"proc-macro2",
"quote",
@ -322,9 +322,9 @@ dependencies = [
[[package]]
name = "smallvec"
version = "1.11.1"
version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a"
checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
[[package]]
name = "spdx"
@ -337,9 +337,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.39"
version = "2.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a"
checksum = "13fa70a4ee923979ffb522cacce59d34421ebdea5625e1073c4326ef9d2dd42e"
dependencies = [
"proc-macro2",
"quote",
@ -389,9 +389,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
[[package]]
name = "unicode-bidi"
version = "0.3.13"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416"
[[package]]
name = "unicode-ident"
@ -422,8 +422,8 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
[[package]]
name = "uqbar_process_lib"
version = "0.3.0"
source = "git+ssh://git@github.com/uqbar-dao/process_lib.git?rev=5e1b94a#5e1b94ae2f85c66da33ec52117a72b90d53c4d22"
version = "0.4.0"
source = "git+ssh://git@github.com/uqbar-dao/process_lib.git?rev=3ea3a23#3ea3a23de46cda8ebe1ea8f3b9f764b57e7feada"
dependencies = [
"anyhow",
"bincode",
@ -461,18 +461,18 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm-encoder"
version = "0.36.2"
version = "0.38.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "822b645bf4f2446b949776ffca47e2af60b167209ffb70814ef8779d299cd421"
checksum = "0ad2b51884de9c7f4fe2fd1043fccb8dcad4b1e29558146ee57a144d15779f3f"
dependencies = [
"leb128",
]
[[package]]
name = "wasm-metadata"
version = "0.10.11"
version = "0.10.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2167ce53b2faa16a92c6cafd4942cff16c9a4fa0c5a5a0a41131ee4e49fc055f"
checksum = "d835d67708f6374937c550ad8dd1d17c616ae009e3f00d7a0ac9f7825e78c36a"
dependencies = [
"anyhow",
"indexmap",
@ -486,9 +486,9 @@ dependencies = [
[[package]]
name = "wasmparser"
version = "0.116.1"
version = "0.118.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a58e28b80dd8340cb07b8242ae654756161f6fc8d0038123d679b7b99964fa50"
checksum = "95ee9723b928e735d53000dec9eae7b07a60e490c85ab54abb66659fc61bfcd9"
dependencies = [
"indexmap",
"semver",
@ -496,8 +496,8 @@ dependencies = [
[[package]]
name = "wit-bindgen"
version = "0.13.1"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d"
version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [
"bitflags",
"wit-bindgen-rust-macro",
@ -505,8 +505,8 @@ dependencies = [
[[package]]
name = "wit-bindgen-core"
version = "0.13.1"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d"
version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [
"anyhow",
"wit-component",
@ -515,8 +515,8 @@ dependencies = [
[[package]]
name = "wit-bindgen-rust"
version = "0.13.2"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d"
version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [
"anyhow",
"heck",
@ -527,8 +527,8 @@ dependencies = [
[[package]]
name = "wit-bindgen-rust-macro"
version = "0.13.1"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d"
version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [
"anyhow",
"proc-macro2",
@ -541,9 +541,9 @@ dependencies = [
[[package]]
name = "wit-component"
version = "0.17.0"
version = "0.18.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "480cc1a078b305c1b8510f7c455c76cbd008ee49935f3a6c5fd5e937d8d95b1e"
checksum = "5b8a35a2a9992898c9d27f1664001860595a4bc99d32dd3599d547412e17d7e2"
dependencies = [
"anyhow",
"bitflags",
@ -560,9 +560,9 @@ dependencies = [
[[package]]
name = "wit-parser"
version = "0.12.2"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43771ee863a16ec4ecf9da0fc65c3bbd4a1235c8e3da5f094b562894843dfa76"
checksum = "15df6b7b28ce94b8be39d8df5cb21a08a4f3b9f33b631aedb4aa5776f785ead3"
dependencies = [
"anyhow",
"id-arena",

View File

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

View File

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

View File

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

View File

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

View File

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

103
modules/chess/Cargo.lock generated
View File

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

View File

@ -1,10 +1,8 @@
[package]
name = "chess"
version = "0.1.0"
version = "0.2.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[profile.release]
panic = "abort"
opt-level = "s"
@ -15,10 +13,11 @@ anyhow = "1.0"
base64 = "0.13"
bincode = "1.3.3"
pleco = "0.5"
serde = {version = "1.0", features = ["derive"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
uqbar_process_lib = { git = "ssh://git@github.com/uqbar-dao/process_lib.git", rev = "5e1b94a" }
wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "5390bab780733f1660d14c254ec985df2816bf1d" }
url = "*"
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]
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",
"request_networking": true,
"request_messaging": [
"net:sys:uqbar"
],
"grant_messaging": [
"http_server:sys:uqbar"
],
"public": false
"public": true
}
]

View File

@ -1,39 +1,45 @@
#![feature(let_chains)]
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
extern crate base64;
extern crate pleco;
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::{
get_payload, get_typed_state, grant_messaging, http, println, receive, set_state, Address,
Message, Payload, ProcessId, Request, Response,
await_message, call_init, get_payload, get_typed_state, http, println, set_state, Address,
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",
world: "process",
exports: {
world: Component,
},
});
//
// Our "chess protocol" request/response format. We'll always serialize these
// to a byte vector and send them over IPC.
//
struct Component;
#[derive(Clone, Debug)]
pub struct Game {
pub id: String, // the node with whom we are playing
pub turns: u64,
pub board: Board,
pub white: String,
pub black: String,
pub ended: bool,
#[derive(Debug, Serialize, Deserialize)]
enum ChessRequest {
NewGame { white: String, black: String },
Move { game_id: String, move_str: String },
Resign(String),
}
#[derive(Debug, Eq, PartialEq, Serialize, Deserialize)]
enum ChessResponse {
NewGameAccepted,
NewGameRejected,
MoveAccepted,
MoveRejected,
}
//
// Our serializable state format.
//
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct StoredGame {
struct Game {
pub id: String, // the node with whom we are playing
pub turns: u64,
pub board: String,
@ -42,280 +48,398 @@ pub struct StoredGame {
pub ended: bool,
}
#[derive(Clone, Debug)]
pub struct ChessState {
#[derive(Debug, Serialize, Deserialize)]
struct ChessState {
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)]
pub struct StoredChessState {
pub games: HashMap<String, StoredGame>, // game is by opposing player id
pub records: HashMap<String, (u64, u64, u64)>, // wins, losses, draws
#[derive(Debug, Serialize, Deserialize)]
struct StoredChessState {
pub games: HashMap<String, Game>, // game is by opposing player id
}
const CHESS_PAGE: &str = include_str!("../pkg/chess.html");
const CHESS_JS: &str = include_str!("../pkg/index.js");
const CHESS_CSS: &str = include_str!("../pkg/index.css");
fn save_chess_state(state: &ChessState) {
set_state(&bincode::serialize(&state.games).unwrap());
}
impl Guest for Component {
fn init(our: String) {
let our = Address::from_str(&our).unwrap();
println!("{our}: start");
fn load_chess_state() -> ChessState {
match get_typed_state(|bytes| Ok(bincode::deserialize::<HashMap<String, Game>>(bytes)?)) {
Some(games) => ChessState {
games,
clients: HashSet::new(),
},
None => ChessState {
games: HashMap::new(),
clients: HashSet::new(),
},
}
}
grant_messaging(
&our,
vec![ProcessId::new(Some("http_server"), "sys", "uqbar")],
);
fn send_ws_update(our: &Address, game: &Game, open_channels: &HashSet<u32>) -> anyhow::Result<()> {
for channel in open_channels {
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 /
// dynamically handle requests to /games
http::bind_http_static_path(
"/",
true,
false,
Some("text/html".to_string()),
CHESS_PAGE
.replace("${node}", &our.node)
.replace("${process}", &our.process.to_string())
// TODO serve these independently on paths..
// 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();
// Boilerplate: generate the wasm bindings for an Uqbar app
wit_bindgen::generate!({
path: "../../wit",
world: "process",
exports: {
world: Component,
},
});
// After generating bindings, use this macro to define the Component struct
// and its init() function, which the kernel will look for on startup.
call_init!(initialize);
let mut state: ChessState = match get_typed_state(|bytes| {
Ok(bincode::deserialize::<StoredChessState>(bytes)?)
}) {
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(),
},
};
fn initialize(our: Address) {
// A little printout to show in terminal that the process has started.
println!("{} by {}: start", our.process(), our.publisher());
loop {
let Ok((source, message)) = receive() else {
println!("chess: got network error");
// serve static page at /index.html, /index.js, /index.css
// dynamically handle requests to /games
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;
};
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(
our: &Address,
source: &Address,
request: &wit::Request,
state: &mut ChessState,
) -> anyhow::Result<()> {
if source.process == "chess:chess:uqbar" {
let message_json = serde_json::from_slice::<serde_json::Value>(&request.ipc)?;
handle_chess_request(our, source, message_json, state)
} else if source.process.to_string() == "http_server:sys:uqbar" {
let http_request = serde_json::from_slice::<http::IncomingHttpRequest>(&request.ipc)?;
handle_http_request(our, http_request, state)
/// Handle chess protocol messages from ourself *or* other nodes.
fn handle_request(our: &Address, message: &Message, state: &mut ChessState) -> anyhow::Result<()> {
// Throw away responses. We never expect any responses *here*, because for every
// chess protocol request, we *await* its response in-place. This is appropriate
// for direct node<>node comms, less appropriate for other circumstances...
if !message.is_request() {
return Err(anyhow::anyhow!("message was response"));
}
// If the request is from another node, handle it as an incoming request.
// Note that we can enforce the ProcessId as well, but it shouldn't be a trusted
// piece of information, since another node can easily spoof any ProcessId on a request.
// 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 {
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(
our: &Address,
source: &Address,
message_json: serde_json::Value,
source_node: &NodeId,
state: &mut ChessState,
action: &ChessRequest,
) -> anyhow::Result<()> {
let action = message_json["action"].as_str().unwrap_or("");
let game_id = &source.node;
println!("chess: handling action from {source_node}: {action:?}");
// 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 {
"new_game" => {
// make a new game with source.node if the current game has ended
if let Some(game) = state.games.get(game_id) {
if !game.ended {
return Response::new()
.ipc(vec![])
.payload(Payload {
mime: Some("application/octet-stream".to_string()),
bytes: "conflict".as_bytes().to_vec(),
})
.send();
}
ChessRequest::NewGame { white, black } => {
// Make a new game with source.node
// This will replace any existing game with source.node!
if state.games.contains_key(game_id) {
println!("chess: resetting game with {game_id} on their request!");
}
let game = Game {
id: game_id.to_string(),
turns: 0,
board: Board::start_pos(),
white: message_json["white"]
.as_str()
.unwrap_or(game_id)
.to_string(),
black: message_json["black"]
.as_str()
.unwrap_or(&our.node)
.to_string(),
board: Board::start_pos().fen(),
white: white.to_string(),
black: black.to_string(),
ended: false,
};
state.games.insert(game_id.to_string(), game.clone());
utils::send_ws_update(&our, &game)?;
utils::save_chess_state(&state);
// Use our helper function to persist state after every action.
// The simplest and most trivial way to keep state. You'll want to
// use a database or something in a real app, and consider performance
// 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()
.ipc(vec![])
.payload(Payload {
mime: Some("application/octet-stream".to_string()),
bytes: "success".as_bytes().to_vec(),
})
.ipc(serde_json::to_vec(&ChessResponse::NewGameAccepted)?)
.send()
}
"make_move" => {
// check the move and then update if correct and send WS update
ChessRequest::Move { ref move_str, .. } => {
// 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 {
// If we don't have a game with them, reject the move.
return Response::new()
.ipc(vec![])
.payload(Payload {
mime: Some("application/octet-stream".to_string()),
bytes: "not found".as_bytes().to_vec(),
})
.send();
.ipc(serde_json::to_vec(&ChessResponse::MoveRejected)?)
.send()
};
let valid_move = game
.board
.apply_uci_move(message_json["move"].as_str().unwrap_or(""));
if valid_move {
game.turns += 1;
let checkmate = game.board.checkmate();
let draw = game.board.stalemate();
if checkmate || draw {
// Convert the saved board to one we can manipulate.
let mut board = Board::from_fen(&game.board).unwrap();
if !board.apply_uci_move(move_str) {
// Reject invalid moves!
return Response::new()
.ipc(serde_json::to_vec(&ChessResponse::MoveRejected)?)
.send();
}
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;
let winner = if checkmate {
if game.turns % 2 == 1 {
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));
}
}
}
send_ws_update(&our, &game, &state.clients)?;
save_chess_state(&state);
}
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()
None => {}
}
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(
our: &Address,
http_request: http::IncomingHttpRequest,
state: &mut ChessState,
http_request: &http::IncomingHttpRequest,
) -> anyhow::Result<()> {
if http_request.path()? != "/games" {
if http_request.path()? != "games" {
return http::send_response(
http::StatusCode::NOT_FOUND,
None,
@ -323,20 +447,17 @@ fn handle_http_request(
);
}
match http_request.method.as_str() {
// on GET: give the frontend all of our active games
"GET" => http::send_response(
http::StatusCode::OK,
Some(HashMap::from([(
String::from("Content-Type"),
String::from("application/json"),
)])),
serde_json::to_vec(&serde_json::json!(state
.games
.iter()
.map(|(id, game)| (id.to_string(), utils::json_game(game)))
.collect::<HashMap<String, serde_json::Value>>()))?,
serde_json::to_vec(&state.games)?,
),
// on POST: create a new game
"POST" => {
// create a new game
let Some(payload) = get_payload() else {
return http::send_response(http::StatusCode::BAD_REQUEST, None, vec![]);
};
@ -360,38 +481,33 @@ fn handle_http_request(
.to_string();
// send the other player a new game request
let response = Request::new()
.target((game_id, "chess", "chess", "uqbar"))
.ipc(serde_json::to_vec(&serde_json::json!({
"action": "new_game",
"white": player_white.clone(),
"black": player_black.clone(),
}))?)
.send_and_await_response(30)?;
let Ok(msg) = Request::new()
.target((game_id, our.process.clone()))
.ipc(serde_json::to_vec(&ChessRequest::NewGame {
white: player_white.clone(),
black: player_black.clone(),
})?)
.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, should surface error to FE...
let Ok((_source, Message::Response((resp, _context)))) = response else {
return http::send_response(
http::StatusCode::SERVICE_UNAVAILABLE,
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![]);
if serde_json::from_slice::<ChessResponse>(msg.ipc())? != ChessResponse::NewGameAccepted
{
return Err(anyhow::anyhow!("other player rejected new game request"));
}
// create a new game
let game = Game {
id: game_id.to_string(),
turns: 0,
board: Board::start_pos(),
board: Board::start_pos().fen(),
white: player_white,
black: player_black,
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);
utils::save_chess_state(&state);
save_chess_state(&state);
http::send_response(
http::StatusCode::OK,
Some(HashMap::from([(
@ -401,8 +517,8 @@ fn handle_http_request(
body,
)
}
// on PUT: make a move
"PUT" => {
// make a move
let Some(payload) = get_payload() else {
return http::send_response(http::StatusCode::BAD_REQUEST, None, vec![]);
};
@ -420,71 +536,38 @@ fn handle_http_request(
} else if game.ended {
return http::send_response(http::StatusCode::CONFLICT, None, vec![]);
}
let move_str = payload_json["move"].as_str().unwrap_or("");
if !game.board.apply_uci_move(move_str) {
let Some(move_str) = payload_json["move"].as_str() else {
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
return http::send_response(http::StatusCode::BAD_REQUEST, None, vec![]);
}
// send the move to the other player
// check if the game is over
// if so, update the records
let response = Request::new()
.target((game_id, "chess", "chess", "uqbar"))
.ipc(serde_json::to_vec(&serde_json::json!({
"action": "make_move",
"move": move_str,
}))?)
.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::BAD_REQUEST, None, vec![]);
};
if resp.ipc != "success".as_bytes() {
return http::send_response(http::StatusCode::SERVICE_UNAVAILABLE, None, vec![]);
let Ok(msg) = Request::new()
.target((game_id, our.process.clone()))
.ipc(serde_json::to_vec(&ChessRequest::Move {
game_id: game_id.to_string(),
move_str: move_str.to_string(),
})?)
.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>(msg.ipc())? != ChessResponse::MoveAccepted {
return Err(anyhow::anyhow!("other player rejected our move"));
}
// update the game
game.turns += 1;
let checkmate = game.board.checkmate();
let draw = game.board.stalemate();
if checkmate || draw {
if board.checkmate() || board.stalemate() {
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
let body = serde_json::to_vec(&utils::json_game(&game))?;
utils::save_chess_state(&state);
game.board = board.fen();
// update state and return to FE
let body = serde_json::to_vec(&game)?;
save_chess_state(&state);
// return the game
http::send_response(
http::StatusCode::OK,
@ -495,41 +578,22 @@ fn handle_http_request(
body,
)
}
// on DELETE: end the game
"DELETE" => {
// "end the game"?
let query_params = http_request.query_params()?;
let Some(game_id) = query_params.get("id") else {
let Some(game_id) = http_request.query_params.get("id") else {
return http::send_response(http::StatusCode::BAD_REQUEST, None, vec![]);
};
let Some(game) = state.games.get_mut(game_id) else {
return http::send_response(http::StatusCode::BAD_REQUEST, None, vec![]);
};
// send the other player an end game request
let response = Request::new()
.target((game_id, "chess", "chess", "uqbar"))
.ipc(serde_json::to_vec(&serde_json::json!({
"action": "end_game",
}))?)
.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![]);
}
Request::new()
.target((game_id.as_str(), our.process.clone()))
.ipc(serde_json::to_vec(&ChessRequest::Resign(our.node.clone()))?)
.send()?;
game.ended = true;
if let Some(record) = state.records.get_mut(&game.id) {
record.1 += 1;
} 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);
let body = serde_json::to_vec(&game)?;
save_chess_state(&state);
http::send_response(
http::StatusCode::OK,
Some(HashMap::from([(
@ -539,11 +603,7 @@ fn handle_http_request(
body,
)
}
_ => Response::new()
.ipc(serde_json::to_vec(&http::HttpResponse {
status: 405,
headers: HashMap::new(),
})?)
.send(),
// Any other method will be rejected.
_ => http::send_response(http::StatusCode::METHOD_NOT_ALLOWED, None, vec![]),
}
}

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

View File

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

View File

@ -196,7 +196,7 @@
<h4>Apps:</h4>
<!-- <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>
<script>window.ourName = window.our = '${our}'</script>
<script>

View File

@ -1,7 +1,7 @@
#![feature(let_chains)]
use uqbar_process_lib::{
grant_messaging, http::bind_http_static_path, http::HttpServerError, println, receive, Address,
Message, ProcessId, Response,
await_message, grant_messaging, http::bind_http_static_path, http::HttpServerError, println, Address,
Message, ProcessId,
};
wit_bindgen::generate!({
@ -44,20 +44,21 @@ fn main(our: Address) -> anyhow::Result<()> {
)?;
loop {
let Ok((ref source, ref message)) = receive() else {
let Ok(ref message) = await_message() else {
println!("homepage: got network error??");
continue;
};
if let Message::Response((ref msg, _)) = message
if let Message::Response { source, ipc, ..} = message
&& 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(Err(e)) => println!("homepage: got error from http_server: {e}"),
Err(_e) => println!("homepage: got malformed message from http_server!"),
}
} 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",
"proc-macro2",
"quote",
"syn 2.0.39",
"syn 2.0.40",
"syn-solidity",
"tiny-keccak",
]
@ -192,12 +192,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "errno"
version = "0.3.5"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860"
checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
dependencies = [
"libc",
"windows-sys",
"windows-sys 0.52.0",
]
[[package]]
@ -223,9 +223,9 @@ dependencies = [
[[package]]
name = "getrandom"
version = "0.2.10"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f"
dependencies = [
"cfg-if",
"libc",
@ -234,9 +234,9 @@ dependencies = [
[[package]]
name = "hashbrown"
version = "0.14.2"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156"
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
[[package]]
name = "heck"
@ -299,9 +299,9 @@ dependencies = [
[[package]]
name = "itoa"
version = "1.0.9"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
[[package]]
name = "lazy_static"
@ -317,9 +317,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67"
[[package]]
name = "libc"
version = "0.2.150"
version = "0.2.151"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4"
[[package]]
name = "libm"
@ -329,9 +329,9 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
[[package]]
name = "linux-raw-sys"
version = "0.4.10"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f"
checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456"
[[package]]
name = "log"
@ -369,18 +369,18 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "proc-macro2"
version = "1.0.69"
version = "1.0.70"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b"
dependencies = [
"unicode-ident",
]
[[package]]
name = "proptest"
version = "1.3.1"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c003ac8c77cb07bb74f5f198bce836a689bcd5a42574612bf14d17bfd08c20e"
checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf"
dependencies = [
"bit-set",
"bit-vec",
@ -477,9 +477,9 @@ dependencies = [
[[package]]
name = "regex-syntax"
version = "0.7.5"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
[[package]]
name = "rmp"
@ -505,9 +505,9 @@ dependencies = [
[[package]]
name = "ruint"
version = "1.11.0"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "724fd11728a3804e9944b14cab63825024c40bf42f8af87c8b5d97c4bbacf426"
checksum = "608a5726529f2f0ef81b8fde9873c4bb829d6b5b5ca6be4d97345ddf0749c825"
dependencies = [
"proptest",
"rand",
@ -534,15 +534,15 @@ dependencies = [
[[package]]
name = "rustix"
version = "0.38.21"
version = "0.38.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3"
checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316"
dependencies = [
"bitflags 2.4.1",
"errno",
"libc",
"linux-raw-sys",
"windows-sys",
"windows-sys 0.52.0",
]
[[package]]
@ -559,9 +559,9 @@ dependencies = [
[[package]]
name = "ryu"
version = "1.0.15"
version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
[[package]]
name = "semver"
@ -571,22 +571,22 @@ checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090"
[[package]]
name = "serde"
version = "1.0.192"
version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001"
checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.192"
version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1"
checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.39",
"syn 2.0.40",
]
[[package]]
@ -602,9 +602,9 @@ dependencies = [
[[package]]
name = "smallvec"
version = "1.11.1"
version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a"
checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
[[package]]
name = "smol_str"
@ -637,9 +637,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.39"
version = "2.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a"
checksum = "13fa70a4ee923979ffb522cacce59d34421ebdea5625e1073c4326ef9d2dd42e"
dependencies = [
"proc-macro2",
"quote",
@ -655,7 +655,7 @@ dependencies = [
"paste",
"proc-macro2",
"quote",
"syn 2.0.39",
"syn 2.0.40",
]
[[package]]
@ -668,7 +668,7 @@ dependencies = [
"fastrand",
"redox_syscall",
"rustix",
"windows-sys",
"windows-sys 0.48.0",
]
[[package]]
@ -688,7 +688,7 @@ checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.39",
"syn 2.0.40",
]
[[package]]
@ -723,9 +723,9 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94"
[[package]]
name = "unicode-bidi"
version = "0.3.13"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416"
[[package]]
name = "unicode-ident"
@ -756,8 +756,8 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
[[package]]
name = "uqbar_process_lib"
version = "0.3.0"
source = "git+ssh://git@github.com/uqbar-dao/process_lib.git?rev=5e1b94a#5e1b94ae2f85c66da33ec52117a72b90d53c4d22"
version = "0.4.0"
source = "git+ssh://git@github.com/uqbar-dao/process_lib.git?rev=3ea3a23#3ea3a23de46cda8ebe1ea8f3b9f764b57e7feada"
dependencies = [
"anyhow",
"bincode",
@ -804,18 +804,18 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm-encoder"
version = "0.36.2"
version = "0.38.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "822b645bf4f2446b949776ffca47e2af60b167209ffb70814ef8779d299cd421"
checksum = "0ad2b51884de9c7f4fe2fd1043fccb8dcad4b1e29558146ee57a144d15779f3f"
dependencies = [
"leb128",
]
[[package]]
name = "wasm-metadata"
version = "0.10.11"
version = "0.10.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2167ce53b2faa16a92c6cafd4942cff16c9a4fa0c5a5a0a41131ee4e49fc055f"
checksum = "d835d67708f6374937c550ad8dd1d17c616ae009e3f00d7a0ac9f7825e78c36a"
dependencies = [
"anyhow",
"indexmap",
@ -829,9 +829,9 @@ dependencies = [
[[package]]
name = "wasmparser"
version = "0.116.1"
version = "0.118.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a58e28b80dd8340cb07b8242ae654756161f6fc8d0038123d679b7b99964fa50"
checksum = "95ee9723b928e735d53000dec9eae7b07a60e490c85ab54abb66659fc61bfcd9"
dependencies = [
"indexmap",
"semver",
@ -843,7 +843,16 @@ version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
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]]
@ -852,13 +861,28 @@ version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
"windows_aarch64_gnullvm 0.48.5",
"windows_aarch64_msvc 0.48.5",
"windows_i686_gnu 0.48.5",
"windows_i686_msvc 0.48.5",
"windows_x86_64_gnu 0.48.5",
"windows_x86_64_gnullvm 0.48.5",
"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]]
@ -867,46 +891,88 @@ version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_gnu"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_i686_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
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]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
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]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
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]]
name = "wit-bindgen"
version = "0.13.1"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d"
version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [
"bitflags 2.4.1",
"wit-bindgen-rust-macro",
@ -914,8 +980,8 @@ dependencies = [
[[package]]
name = "wit-bindgen-core"
version = "0.13.1"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d"
version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [
"anyhow",
"wit-component",
@ -924,8 +990,8 @@ dependencies = [
[[package]]
name = "wit-bindgen-rust"
version = "0.13.2"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d"
version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [
"anyhow",
"heck",
@ -936,13 +1002,13 @@ dependencies = [
[[package]]
name = "wit-bindgen-rust-macro"
version = "0.13.1"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d"
version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [
"anyhow",
"proc-macro2",
"quote",
"syn 2.0.39",
"syn 2.0.40",
"wit-bindgen-core",
"wit-bindgen-rust",
"wit-component",
@ -950,9 +1016,9 @@ dependencies = [
[[package]]
name = "wit-component"
version = "0.17.0"
version = "0.18.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "480cc1a078b305c1b8510f7c455c76cbd008ee49935f3a6c5fd5e937d8d95b1e"
checksum = "5b8a35a2a9992898c9d27f1664001860595a4bc99d32dd3599d547412e17d7e2"
dependencies = [
"anyhow",
"bitflags 2.4.1",
@ -969,9 +1035,9 @@ dependencies = [
[[package]]
name = "wit-parser"
version = "0.12.2"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43771ee863a16ec4ecf9da0fc65c3bbd4a1235c8e3da5f094b562894843dfa76"
checksum = "15df6b7b28ce94b8be39d8df5cb21a08a4f3b9f33b631aedb4aa5776f785ead3"
dependencies = [
"anyhow",
"id-arena",
@ -986,6 +1052,6 @@ dependencies = [
[[package]]
name = "zeroize"
version = "1.6.0"
version = "1.7.0"
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"
hex = "0.4.3"
rmp-serde = "1.1.2"
serde = {version = "1.0", features = ["derive"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
uqbar_process_lib = { git = "ssh://git@github.com/uqbar-dao/process_lib.git", rev = "5e1b94a" }
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 = "3ea3a23" }
wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "efcc759" }
[lib]
crate-type = ["cdylib"]

View File

@ -6,7 +6,7 @@ use serde_json::json;
use std::collections::HashMap;
use std::string::FromUtf8Error;
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!({
@ -157,18 +157,18 @@ fn main(our: Address, mut state: State) -> anyhow::Result<()> {
http::bind_http_path("/node/:name", false, false)?;
loop {
let Ok((source, message)) = receive() else {
let Ok(message) = await_message() else {
println!("qns_indexer: got network error");
continue;
};
let Message::Request(request) = message else {
let Message::Request { source, ipc, .. } = message else {
// TODO we should store the subscription ID for eth_rpc
// incase we want to cancel/reset it
continue;
};
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 let Some(name) = ipc_json["url_params"]["name"].as_str() {
if let Some(node) = state.nodes.get(name) {
@ -211,7 +211,7 @@ fn main(our: Address, mut state: State) -> anyhow::Result<()> {
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");
continue;
};

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -14,19 +14,14 @@ lto = true
anyhow = "1.0"
bincode = "1.3.3"
indexmap = "2.1"
serde = {version = "1.0", features = ["derive"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
thiserror = "1.0"
uqbar_process_lib = { git = "ssh://git@github.com/uqbar-dao/process_lib.git", rev = "5e1b94a" }
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 = "3ea3a23" }
wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "efcc759" }
[lib]
crate-type = ["cdylib"]
[package.metadata.component]
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, .. }) => {
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");
assert!(input_node_names.len() >= 1);
@ -83,7 +83,7 @@ fn handle_message(
process: child_process_id,
})
.ipc(ipc)
.expects_response(15)
.expects_response(test_timeout)
.send()?;
}
},

View File

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

View File

@ -136,38 +136,36 @@ async fn handle_message(
match client.execute(request).await {
Ok(response) => {
if expects_response.is_some() {
let _ = send_to_loop
.send(KernelMessage {
id,
source: Address {
node: our.to_string(),
process: ProcessId::new(Some("http_client"), "sys", "uqbar"),
let _ = send_to_loop
.send(KernelMessage {
id,
source: Address {
node: our.to_string(),
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,
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,
},
None,
)),
payload: Some(Payload {
mime: None,
bytes: response.bytes().await.unwrap_or_default().to_vec(),
}),
signed_capabilities: None,
})
.await;
}
None,
)),
payload: Some(Payload {
mime: None,
bytes: response.bytes().await.unwrap_or_default().to_vec(),
}),
signed_capabilities: None,
})
.await;
}
Err(e) => {
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::utils::*;
use crate::register;
use crate::types::*;
use crate::{keygen, register};
use anyhow::Result;
use dashmap::DashMap;
use futures::{SinkExt, StreamExt};
use http::uri::Authority;
use route_recognizer::Router;
use sha2::{Digest, Sha256};
use std::collections::HashMap;
use std::net::SocketAddr;
use std::sync::Arc;
@ -14,7 +16,12 @@ use warp::http::{header::HeaderValue, StatusCode};
use warp::ws::{WebSocket, Ws};
use warp::{Filter, Reply};
#[cfg(not(feature = "simulation-mode"))]
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
/// 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 {
pub app: ProcessId,
pub secure_subdomain: Option<String>,
pub authenticated: bool,
pub local_only: bool,
pub static_content: Option<Payload>, // TODO store in filesystem and cache
@ -55,26 +63,28 @@ struct BoundPath {
pub async fn http_server(
our_name: String,
our_port: u16,
encoded_keyfile: Vec<u8>,
jwt_secret_bytes: Vec<u8>,
mut recv_in_server: MessageReceiver,
send_to_loop: MessageSender,
print_tx: PrintSender,
) -> Result<()> {
let our_name = Arc::new(our_name);
let encoded_keyfile = Arc::new(encoded_keyfile);
let jwt_secret_bytes = Arc::new(jwt_secret_bytes);
let http_response_senders: HttpResponseSenders = 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 rpc_bound_path = BoundPath {
app: ProcessId::from_str("rpc:sys:uqbar").unwrap(),
secure_subdomain: None, // TODO maybe RPC should have subdomain?
authenticated: false,
local_only: true,
static_content: None,
};
bindings_map.add("/rpc:sys:uqbar/message", rpc_bound_path);
let path_bindings: PathBindings = Arc::new(RwLock::new(bindings_map));
tokio::spawn(serve(
@ -83,6 +93,7 @@ pub async fn http_server(
http_response_senders.clone(),
path_bindings.clone(),
ws_senders.clone(),
encoded_keyfile.clone(),
jwt_secret_bytes.clone(),
send_to_loop.clone(),
print_tx.clone(),
@ -95,9 +106,7 @@ pub async fn http_server(
http_response_senders.clone(),
path_bindings.clone(),
ws_senders.clone(),
jwt_secret_bytes.clone(),
send_to_loop.clone(),
print_tx.clone(),
)
.await;
}
@ -112,6 +121,7 @@ async fn serve(
http_response_senders: HttpResponseSenders,
path_bindings: PathBindings,
ws_senders: WebSocketSenders,
encoded_keyfile: Arc<Vec<u8>>,
jwt_secret_bytes: Arc<Vec<u8>>,
send_to_loop: MessageSender,
print_tx: PrintSender,
@ -123,7 +133,7 @@ async fn serve(
})
.await;
// Filter to receive websockets
// filter to receive websockets
let cloned_msg_tx = send_to_loop.clone();
let cloned_our = our.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()
.and(warp::addr::remote())
.and(warp::filters::host::optional())
.and(warp::path::full())
.and(warp::query::<HashMap<String, String>>())
.and(warp::filters::header::headers_cloned())
.and(warp::filters::body::bytes())
.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 || jwt_secret_bytes.clone()))
.and(warp::any().map(move || send_to_loop.clone()))
.and(warp::any().map(move || print_tx.clone()))
.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)
.run(([0, 0, 0, 0], our_port))
.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(
method: warp::http::Method,
socket_addr: Option<SocketAddr>,
host: Option<Authority>,
path: warp::path::FullPath,
query_params: HashMap<String, String>,
headers: warp::http::HeaderMap,
body: warp::hyper::body::Bytes,
our: Arc<String>,
@ -185,11 +263,18 @@ async fn http_handler(
path_bindings: PathBindings,
jwt_secret_bytes: Arc<Vec<u8>>,
send_to_loop: MessageSender,
print_tx: PrintSender,
) -> Result<impl warp::Reply, warp::Rejection> {
// TODO this is all so dirty. Figure out what actually matters.
// trim trailing "/"
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 serialized_headers = serialize_headers(&headers);
let path_bindings = path_bindings.read().await;
@ -200,11 +285,55 @@ async fn http_handler(
let bound_path = route.handler();
if bound_path.authenticated {
let auth_token = serialized_headers
.get("cookie")
.cloned()
.unwrap_or_default();
if !auth_cookie_valid(&our, &auth_token, &jwt_secret_bytes) {
match serialized_headers.get("cookie") {
Some(auth_token) => {
// they have an auth token, validate
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());
}
}
@ -258,14 +387,20 @@ async fn http_handler(
message: Message::Request(Request {
inherit: false,
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()),
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,
})
query_params,
}))
.unwrap(),
metadata: None,
metadata: Some("http".into()),
}),
payload: Some(Payload {
mime: None,
@ -390,15 +525,28 @@ async fn maintain_websocket(
jwt_secret_bytes: Arc<Vec<u8>>,
ws_senders: WebSocketSenders,
send_to_loop: MessageSender,
_print_tx: PrintSender,
print_tx: PrintSender,
) {
let (mut write_stream, mut read_stream) = ws.split();
// first, receive a message from client that contains the target process
// 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 {
// 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.close().await;
return;
@ -406,6 +554,12 @@ async fn maintain_websocket(
let Ok(ws_register) = serde_json::from_slice::<WsRegister>(register_msg.as_bytes()) else {
// 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.close().await;
return;
@ -413,11 +567,24 @@ async fn maintain_websocket(
let Ok(owner_process) = ProcessId::from_str(&ws_register.target_process) else {
// 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.close().await;
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 {
// invalid auth token, exit
let stream = write_stream.reunite(read_stream).unwrap();
@ -453,8 +620,8 @@ async fn maintain_websocket(
message: Message::Request(Request {
inherit: false,
expects_response: None,
ipc: serde_json::to_vec(&HttpServerAction::WebSocketOpen(ws_channel_id)).unwrap(),
metadata: None,
ipc: serde_json::to_vec(&HttpServerRequest::WebSocketOpen(ws_channel_id)).unwrap(),
metadata: Some("ws".into()),
}),
payload: None,
signed_capabilities: None,
@ -477,6 +644,13 @@ async fn maintain_websocket(
return;
};
let _ = print_tx
.send(Printout {
verbosity: 1,
content: format!("websocket channel {ws_channel_id} opened"),
})
.await;
loop {
tokio::select! {
read = read_stream.next() => {
@ -508,11 +682,11 @@ async fn maintain_websocket(
message: Message::Request(Request {
inherit: false,
expects_response: None,
ipc: serde_json::to_vec(&HttpServerAction::WebSocketPush {
ipc: serde_json::to_vec(&HttpServerRequest::WebSocketPush {
channel_id: ws_channel_id,
message_type: WsMessageType::Binary,
}).unwrap(),
metadata: None,
metadata: Some("ws".into()),
}),
payload: Some(Payload {
mime: None,
@ -563,8 +737,8 @@ async fn websocket_close(
message: Message::Request(Request {
inherit: false,
expects_response: None,
ipc: serde_json::to_vec(&HttpServerAction::WebSocketClose(channel_id)).unwrap(),
metadata: None,
ipc: serde_json::to_vec(&HttpServerRequest::WebSocketClose(channel_id)).unwrap(),
metadata: Some("ws".into()),
}),
payload: Some(Payload {
mime: None,
@ -584,9 +758,7 @@ async fn handle_app_message(
http_response_senders: HttpResponseSenders,
path_bindings: PathBindings,
ws_senders: WebSocketSenders,
jwt_secret_bytes: Arc<Vec<u8>>,
send_to_loop: MessageSender,
print_tx: PrintSender,
) {
// when we get a Response, try to match it to an outstanding HTTP
// request and send it there.
@ -618,60 +790,10 @@ async fn handle_app_message(
.unwrap(),
));
} 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.
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((
HttpResponse {
status: response.status,
@ -722,6 +844,7 @@ async fn handle_app_message(
&normalize_path(&path),
BoundPath {
app: km.source.process.clone(),
secure_subdomain: None,
authenticated,
local_only,
static_content: None,
@ -743,6 +866,7 @@ async fn handle_app_message(
&normalize_path(&path),
BoundPath {
app: km.source.process.clone(),
secure_subdomain: None,
authenticated,
local_only,
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;
}
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(_) => {
// we cannot receive these, only send them to processes
send_action_response(

View File

@ -5,12 +5,32 @@ use thiserror::Error;
/// 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.
#[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)]
pub struct IncomingHttpRequest {
pub source_socket_addr: Option<String>, // will parse to SocketAddr
pub method: String, // will parse to http::Method
pub raw_path: String,
pub headers: HashMap<String, String>,
pub query_params: HashMap<String, String>,
// 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.
/// You can also send [`WebSocketPush`], which allows you to push messages
/// across an existing open WebSocket connection.
/// You can also send [`type@HttpServerAction::WebSocketPush`], which
/// allows you to push messages across an existing open WebSocket connection.
///
/// If a response is expected, all HttpServerActions will return a Response
/// with the shape Result<(), HttpServerActionError> serialized to JSON.
@ -67,23 +87,41 @@ pub enum HttpServerAction {
/// be the static file to serve at this path.
Bind {
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,
/// Set whether requests can be fielded from anywhere, or only the loopback address.
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,
},
/// 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),
/// Processes can both SEND and RECEIVE this kind of request.
/// When sent, expects a payload containing the WebSocket message bytes to send.
WebSocketPush {
channel_id: u32,
message_type: WsMessageType,
},
/// Processes can both SEND and RECEIVE this kind of request. Sending will
/// close a socket the process controls. Receiving will indicate that the
/// client closed the socket.
/// Sending will close a socket the process controls.
WebSocketClose(u32),
}

View File

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

View File

@ -23,7 +23,7 @@ pub fn encode_keyfile(
password: String,
username: String,
routers: Vec<String>,
networking_key: Document,
networking_key: &[u8],
jwt: Vec<u8>,
file_key: Vec<u8>,
) -> Vec<u8> {
@ -49,9 +49,7 @@ pub fn encode_keyfile(
let jwt_nonce = Aes256Gcm::generate_nonce(&mut OsRng);
let file_nonce = Aes256Gcm::generate_nonce(&mut OsRng);
let keyciphertext: Vec<u8> = cipher
.encrypt(&network_nonce, networking_key.as_ref())
.unwrap();
let keyciphertext: Vec<u8> = cipher.encrypt(&network_nonce, networking_key).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();
@ -66,9 +64,9 @@ pub fn encode_keyfile(
.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) =
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")?;
// 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) =
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")?;
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 vfs;
// extensions
#[cfg(feature = "llm")]
mod llm;
const EVENT_LOOP_CHANNEL_CAPACITY: usize = 10_000;
const EVENT_LOOP_DEBUG_CHANNEL_CAPACITY: usize = 50;
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 VFS_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");
@ -51,7 +45,7 @@ async fn serve_register_fe(
our_ip: String,
http_server_port: u16,
rpc_url: String,
) -> (Identity, Keyfile) {
) -> (Identity, Vec<u8>, Keyfile) {
// check if we have keys saved on disk, encrypted
// 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.
let (kill_tx, kill_rx) = oneshot::channel::<bool>();
let disk_keyfile = match fs::read(format!("{}/.keys", home_directory_path)).await {
Ok(keyfile) => keyfile,
Err(_) => Vec::new(),
};
let disk_keyfile: Option<Vec<u8>> = fs::read(format!("{}/.keys", home_directory_path))
.await
.ok();
let (tx, mut rx) = mpsc::channel::<(Identity, Keyfile, Vec<u8>)>(1);
let (our, decoded_keyfile, encoded_keyfile) = tokio::select! {
@ -80,20 +73,16 @@ async fn serve_register_fe(
}
};
println!(
"saving encrypted networking keys to {}/.keys",
home_directory_path
);
fs::write(format!("{}/.keys", home_directory_path), encoded_keyfile)
.await
.unwrap();
println!("registration complete!");
fs::write(
format!("{}/.keys", home_directory_path),
encoded_keyfile.clone(),
)
.await
.unwrap();
let _ = kill_tx.send(true);
(our, decoded_keyfile)
(our, encoded_keyfile, decoded_keyfile)
}
#[tokio::main]
@ -123,9 +112,6 @@ async fn main() {
.value_parser(value_parser!(u16)),
);
#[cfg(feature = "llm")]
let app = app.arg(arg!(--llm <LLM_URL> "LLM endpoint"));
let matches = app.get_matches();
let home_directory_path = matches.get_one::<String>("home").unwrap();
@ -145,9 +131,6 @@ async fn main() {
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 {
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
let (print_sender, print_receiver): (PrintSender, PrintReceiver) =
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...");
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();
println!("runtime bound port {}\r", http_server_port);
println!(
"login or register at http://localhost:{}\r",
http_server_port
);
#[cfg(not(feature = "simulation-mode"))]
let (our, decoded_keyfile) = serve_register_fe(
let (our, encoded_keyfile, decoded_keyfile) = serve_register_fe(
&home_directory_path,
our_ip.to_string(),
http_server_port.clone(),
@ -221,7 +199,7 @@ async fn main() {
)
.await;
#[cfg(feature = "simulation-mode")]
let (our, decoded_keyfile) = match fake_node_name {
let (our, encoded_keyfile, decoded_keyfile) = match fake_node_name {
None => {
match password {
None => match rpc_url {
@ -240,7 +218,7 @@ async fn main() {
match fs::read(format!("{}/.keys", home_directory_path)).await {
Err(e) => panic!("could not read keyfile: {}", e),
Ok(keyfile) => {
match keygen::decode_keyfile(keyfile, &password) {
match keygen::decode_keyfile(&keyfile, &password) {
Err(e) => panic!("could not decode keyfile: {}", e),
Ok(decoded_keyfile) => {
let our = Identity {
@ -257,7 +235,7 @@ async fn main() {
ws_routing: None, // TODO
allowed_routers: decoded_keyfile.routers.clone(),
};
(our, decoded_keyfile)
(our, keyfile, decoded_keyfile)
}
}
}
@ -298,16 +276,19 @@ async fn main() {
password,
name.clone(),
decoded_keyfile.routers.clone(),
networking_keypair,
networking_keypair.as_ref(),
decoded_keyfile.jwt_secret_bytes.clone(),
decoded_keyfile.file_key.clone(),
);
fs::write(format!("{}/.keys", home_directory_path), encoded_keyfile)
.await
.unwrap();
fs::write(
format!("{}/.keys", home_directory_path),
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(
our.name.clone(),
http_server_port,
encoded_keyfile,
decoded_keyfile.jwt_secret_bytes.clone(),
http_server_receiver,
kernel_message_sender.clone(),
@ -448,16 +430,6 @@ async fn main() {
caps_oracle_sender.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,
// unless it was terminal signaling a quit
let quit_msg: String = tokio::select! {

View File

@ -65,7 +65,7 @@ pub async fn maintain_connection(
if km.source.node != peer_name {
let _ = print_tx.send(Printout {
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;
break
} else {
@ -136,7 +136,9 @@ pub async fn maintain_passthrough(mut conn: PassthroughConnection) {
maybe_recv = conn.read_stream_1.next() => {
match maybe_recv {
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();
}
_ => break,
@ -145,7 +147,9 @@ pub async fn maintain_passthrough(mut conn: PassthroughConnection) {
maybe_recv = conn.read_stream_2.next() => {
match maybe_recv {
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();
}
_ => break,

View File

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

View File

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

Binary file not shown.