From 27f19aaf3b818cfbcc3cd311826ec305379ed980 Mon Sep 17 00:00:00 2001 From: jverdicc Date: Sun, 1 Mar 2026 21:28:55 -0500 Subject: [PATCH] fix: migrate discos-cli to current EvidenceOS protocol --- Cargo.lock | 227 +++++++++++++++++++++++++++++++++- crates/discos-cli/Cargo.toml | 3 + crates/discos-cli/src/main.rs | 111 +++++++++-------- 3 files changed, 287 insertions(+), 54 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 41840e1..d69362d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -237,6 +237,16 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" +[[package]] +name = "cc" +version = "1.2.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2" +dependencies = [ + "find-msvc-tools", + "shlex", +] + [[package]] name = "cfg-if" version = "1.0.4" @@ -453,6 +463,7 @@ checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", "crypto-common", + "subtle", ] [[package]] @@ -461,12 +472,17 @@ version = "0.1.0" dependencies = [ "anyhow", "discos-client", + "ed25519-dalek", + "evidenceos-core", + "evidenceos-verifier", "hex", "proptest", "serde", "serde_json", "sha2", "tokio", + "tokio-stream", + "tonic", "wasm-encoder 0.220.1", "wasmparser 0.220.1", "wat", @@ -481,7 +497,10 @@ dependencies = [ "discos-builder", "discos-client", "discos-core", + "evidenceos-core", + "evidenceos-protocol", "proptest", + "semver", "serde", "serde_json", "tempfile", @@ -499,7 +518,9 @@ dependencies = [ "base64", "criterion", "ed25519-dalek", + "evidenceos-auth-protocol", "evidenceos-protocol", + "evidenceos-verifier", "hex", "http", "prost", @@ -582,26 +603,65 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "evidenceos-auth-protocol" +version = "0.1.0" +dependencies = [ + "hex", + "hmac", + "sha2", +] + [[package]] name = "evidenceos-core" version = "0.1.0" dependencies = [ + "evidenceos-verifier", "hex", "serde", + "serde_json", "sha2", + "thiserror", + "wasmparser 0.220.1", ] [[package]] name = "evidenceos-protocol" -version = "0.1.0" +version = "0.1.0-alpha" +source = "git+https://github.com/jverdicc/EvidenceOS.git?rev=92daeb58a28323ed6ee75a89535cf86b4902f3fe#92daeb58a28323ed6ee75a89535cf86b4902f3fe" dependencies = [ "prost", - "prost-build", - "prost-types", + "protoc-bin-vendored", + "sha2", "tonic", "tonic-build", ] +[[package]] +name = "evidenceos-redteam" +version = "0.1.0" +dependencies = [ + "anyhow", + "clap", + "discos-client", + "serde", + "serde_json", + "sha2", + "tokio", + "tokio-stream", + "tonic", +] + +[[package]] +name = "evidenceos-verifier" +version = "0.1.0" +dependencies = [ + "ed25519-dalek", + "evidenceos-protocol", + "sha2", + "thiserror", +] + [[package]] name = "fastrand" version = "2.3.0" @@ -614,6 +674,12 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + [[package]] name = "fixedbitset" version = "0.5.7" @@ -796,6 +862,15 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + [[package]] name = "http" version = "1.4.0" @@ -1277,6 +1352,70 @@ dependencies = [ "prost", ] +[[package]] +name = "protoc-bin-vendored" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1c381df33c98266b5f08186583660090a4ffa0889e76c7e9a5e175f645a67fa" +dependencies = [ + "protoc-bin-vendored-linux-aarch_64", + "protoc-bin-vendored-linux-ppcle_64", + "protoc-bin-vendored-linux-s390_64", + "protoc-bin-vendored-linux-x86_32", + "protoc-bin-vendored-linux-x86_64", + "protoc-bin-vendored-macos-aarch_64", + "protoc-bin-vendored-macos-x86_64", + "protoc-bin-vendored-win32", +] + +[[package]] +name = "protoc-bin-vendored-linux-aarch_64" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c350df4d49b5b9e3ca79f7e646fde2377b199e13cfa87320308397e1f37e1a4c" + +[[package]] +name = "protoc-bin-vendored-linux-ppcle_64" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a55a63e6c7244f19b5c6393f025017eb5d793fd5467823a099740a7a4222440c" + +[[package]] +name = "protoc-bin-vendored-linux-s390_64" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dba5565db4288e935d5330a07c264a4ee8e4a5b4a4e6f4e83fad824cc32f3b0" + +[[package]] +name = "protoc-bin-vendored-linux-x86_32" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8854774b24ee28b7868cd71dccaae8e02a2365e67a4a87a6cd11ee6cdbdf9cf5" + +[[package]] +name = "protoc-bin-vendored-linux-x86_64" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b38b07546580df720fa464ce124c4b03630a6fb83e05c336fea2a241df7e5d78" + +[[package]] +name = "protoc-bin-vendored-macos-aarch_64" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89278a9926ce312e51f1d999fee8825d324d603213344a9a706daa009f1d8092" + +[[package]] +name = "protoc-bin-vendored-macos-x86_64" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81745feda7ccfb9471d7a4de888f0652e806d5795b61480605d4943176299756" + +[[package]] +name = "protoc-bin-vendored-win32" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95067976aca6421a523e491fce939a3e65249bac4b977adee0ee9771568e8aa3" + [[package]] name = "quick-error" version = "1.2.3" @@ -1415,6 +1554,20 @@ version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c" +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.17", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + [[package]] name = "rustc_version" version = "0.4.1" @@ -1437,6 +1590,50 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "rustls" +version = "0.23.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4" +dependencies = [ + "log", + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" +dependencies = [ + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + [[package]] name = "rustversion" version = "1.0.22" @@ -1533,6 +1730,12 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "signature" version = "2.2.0" @@ -1691,6 +1894,16 @@ dependencies = [ "syn", ] +[[package]] +name = "tokio-rustls" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +dependencies = [ + "rustls", + "tokio", +] + [[package]] name = "tokio-stream" version = "0.1.18" @@ -1736,8 +1949,10 @@ dependencies = [ "percent-encoding", "pin-project", "prost", + "rustls-pemfile", "socket2 0.5.10", "tokio", + "tokio-rustls", "tokio-stream", "tower 0.4.13", "tower-layer", @@ -1902,6 +2117,12 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "utf8parse" version = "0.2.2" diff --git a/crates/discos-cli/Cargo.toml b/crates/discos-cli/Cargo.toml index baf1604..1d5485a 100644 --- a/crates/discos-cli/Cargo.toml +++ b/crates/discos-cli/Cargo.toml @@ -13,6 +13,9 @@ discos-core = { path = "../discos-core" } discos-client = { path = "../discos-client" } discos-builder = { path = "../discos-builder" } +evidenceos-core = { path = "../evidenceos-core" } +evidenceos-protocol = { workspace = true } + anyhow = "1" clap = { version = "4", features = ["derive", "env"] } tokio = { version = "1", features = ["rt-multi-thread", "macros"] } diff --git a/crates/discos-cli/src/main.rs b/crates/discos-cli/src/main.rs index 92c2997..a12b232 100644 --- a/crates/discos-cli/src/main.rs +++ b/crates/discos-cli/src/main.rs @@ -663,6 +663,9 @@ async fn run_scenario_live( oracle_num_symbols: 1024, access_credit: 100_000, oracle_id: "default".to_string(), + nullspec_id: String::new(), + dp_epsilon_budget: None, + dp_delta_budget: None, }; let mut create_rpc = tonic::Request::new(create_req); @@ -765,6 +768,7 @@ fn parse_daemon_semver(daemon_version: &str) -> Option { } fn compatibility_error_json(server: &pb::GetServerInfoResponse) -> serde_json::Value { + let feature_flags = format!("{:?}", server.feature_flags); serde_json::json!({ "error": "incompatible_daemon", "expected_protocol_semver": expected_protocol_semver(), @@ -777,7 +781,7 @@ fn compatibility_error_json(server: &pb::GetServerInfoResponse) -> serde_json::V "build_git_commit": server.build_git_commit, "build_time_utc": server.build_time_utc, "daemon_version": server.daemon_version, - "feature_flags": server.feature_flags + "feature_flags": feature_flags } }) } @@ -848,9 +852,10 @@ fn load_scenarios(dir: &Path) -> anyhow::Result> { async fn main() -> anyhow::Result<()> { let args = Args::parse(); tracing_subscriber::fmt() - .with_env_filter(EnvFilter::new(args.log)) + .with_env_filter(EnvFilter::new(args.log.clone())) .init(); + let dual_use_policy = dual_use_policy_from_args(&args); match args.cmd { Command::Health => { let mut client = connect_client(&args).await?; @@ -941,6 +946,7 @@ async fn main() -> anyhow::Result<()> { let mut client = connect_client(&args).await?; assert_server_compatibility(&mut client, args.allow_protocol_drift).await?; let info = client.get_server_info().await?; + let feature_flags = format!("{:?}", info.feature_flags); println!( "{}", serde_json::json!({ @@ -949,7 +955,7 @@ async fn main() -> anyhow::Result<()> { "build_git_commit": info.build_git_commit, "build_time_utc": info.build_time_utc, "daemon_version": info.daemon_version, - "feature_flags": info.feature_flags, + "feature_flags": feature_flags, "expected_protocol_semver": expected_protocol_semver(), "expected_proto_hash": expected_proto_hash(), "allow_protocol_drift": args.allow_protocol_drift @@ -1003,7 +1009,7 @@ async fn main() -> anyhow::Result<()> { ); } }, - Command::Claim { cmd } => match cmd { + Command::Claim { ref cmd } => match cmd { ClaimCommand::Create { claim_name, alpha_micros, @@ -1018,8 +1024,7 @@ async fn main() -> anyhow::Result<()> { } => { validate_oracle_id(&oracle_id)?; let output_schema_id = canonicalize_output_schema_id(&output_schema_id); - let dual_use_policy = dual_use_policy_from_args(&args); - let mut lane = lane; + let mut lane = lane.clone(); match enforce_dual_use_policy( &dual_use_policy, &ClaimSafetyContext { @@ -1073,7 +1078,7 @@ async fn main() -> anyhow::Result<()> { let topic = compute_topic_id( &ClaimMetadata { lane: lane.clone(), - alpha_micros, + alpha_micros: *alpha_micros, epoch_config_ref: epoch_config_ref.clone(), output_schema_id: output_schema_id.clone(), }, @@ -1118,21 +1123,24 @@ async fn main() -> anyhow::Result<()> { .create_claim_v2(pb::CreateClaimV2Request { claim_name: claim_name.clone(), metadata: Some(pb::ClaimMetadataV2 { - lane, - alpha_micros, - epoch_config_ref, - output_schema_id, + lane: lane.clone(), + alpha_micros: *alpha_micros, + epoch_config_ref: epoch_config_ref.clone(), + output_schema_id: output_schema_id.clone(), }), signals: Some(pb::TopicSignalsV2 { semantic_hash: vec![], phys_hir_signature_hash: topic.signals.phys_hir_signature_hash.to_vec(), dependency_merkle_root: vec![], }), - holdout_ref, - epoch_size, - oracle_num_symbols, - access_credit, + holdout_ref: holdout_ref.clone(), + epoch_size: (*epoch_size).into(), + oracle_num_symbols: *oracle_num_symbols, + access_credit: *access_credit, oracle_id: oracle_id.clone(), + nullspec_id: String::new(), + dp_epsilon_budget: None, + dp_delta_budget: None, }) .await .map_err(|e| { @@ -1154,7 +1162,7 @@ async fn main() -> anyhow::Result<()> { } => { let wasm_bytes = fs::read(&wasm).with_context(|| format!("read wasm {}", wasm.display()))?; - let artifact_manifests = manifests + let mut artifacts = manifests .iter() .map(|p| { let bytes = fs::read(p) @@ -1163,37 +1171,31 @@ async fn main() -> anyhow::Result<()> { &serde_json::from_slice::(&bytes) .context("manifest should be json")?, )?; - Ok(pb::ArtifactManifest { - name: p + Ok(pb::Artifact { + artifact_hash: digest.to_vec(), + kind: p .file_name() .unwrap_or_default() .to_string_lossy() .to_string(), - canonical_bytes: bytes, - digest: digest.to_vec(), }) }) .collect::>>()?; + artifacts.push(pb::Artifact { + artifact_hash: wasm_hash_for_bytes(&wasm_bytes).to_vec(), + kind: "wasm_module".to_string(), + }); let mut client = connect_client(&args).await?; assert_server_compatibility(&mut client, args.allow_protocol_drift).await?; let claim_id_bytes = hex_decode_bytes(&claim_id)?; - let artifacts = client + let commit_resp = client .commit_artifacts(pb::CommitArtifactsRequest { - claim_id: claim_id_bytes.clone(), - manifests: artifact_manifests, - }) - .await?; - let wasm = client - .commit_wasm(pb::CommitWasmRequest { claim_id: claim_id_bytes, - wasm_hash: wasm_hash_for_bytes(&wasm_bytes).to_vec(), + artifacts, wasm_module: wasm_bytes, }) .await?; - println!( - "{}", - serde_json::json!({"artifacts_accepted": artifacts.accepted, "wasm_accepted": wasm.accepted}) - ); + println!("{}", serde_json::json!({"state": commit_resp.state})); } ClaimCommand::Freeze { claim_id } => { let mut client = connect_client(&args).await?; @@ -1203,7 +1205,7 @@ async fn main() -> anyhow::Result<()> { claim_id: hex_decode_bytes(&claim_id)?, }) .await?; - println!("{}", serde_json::json!({"frozen": resp.frozen})); + println!("{}", serde_json::json!({"state": resp.state})); } ClaimCommand::Execute { claim_id } => { ensure_certify_transport_security(&args)?; @@ -1231,17 +1233,17 @@ async fn main() -> anyhow::Result<()> { claim_id: hex_decode_bytes(&claim_id)?, }) .await?; - let mut output = if verify_etl { + let mut output = if *verify_etl { let cache_path = cache_file_path(); let cache_entry_key = cache_key(&args.endpoint, &args.kernel_pubkey_hex); let mut cache = load_sth_cache(&cache_path)?; let root: [u8; 32] = resp - .etl_root_hash + .root_hash .clone() .try_into() .map_err(|_| anyhow!("etl root hash must be 32 bytes"))?; - let inclusion = resp.inclusion.context("missing inclusion proof")?; + let inclusion = resp.inclusion_proof.context("missing inclusion proof")?; let inclusion = InclusionProof { leaf_hash: inclusion .leaf_hash @@ -1252,20 +1254,22 @@ async fn main() -> anyhow::Result<()> { audit_path: inclusion .audit_path .into_iter() - .map(|n| { + .map(|n: Vec| { n.try_into() .map_err(|_| anyhow!("audit path node must be 32 bytes")) }) .collect::>>()?, }; - let consistency = resp.consistency.context("missing consistency proof")?; + let consistency = resp + .consistency_proof + .context("missing consistency proof")?; let consistency = ConsistencyProof { old_tree_size: consistency.old_tree_size, new_tree_size: consistency.new_tree_size, path: consistency .path .into_iter() - .map(|n| { + .map(|n: Vec| { n.try_into() .map_err(|_| anyhow!("consistency node must be 32 bytes")) }) @@ -1279,7 +1283,7 @@ async fn main() -> anyhow::Result<()> { &mut cache, &cache_entry_key, CachedSth { - tree_size: resp.etl_tree_size, + tree_size: resp.tree_size, root_hash: root, }, &consistency, @@ -1294,10 +1298,12 @@ async fn main() -> anyhow::Result<()> { if !args.kernel_pubkey_hex.is_empty() { let pubkey = hex_decode_bytes(&args.kernel_pubkey_hex)?; let sth = SignedTreeHead { - tree_size: resp.etl_tree_size, + tree_size: resp.tree_size, root_hash: root, signature: resp - .sth_signature + .signed_tree_head + .context("missing signed tree head")? + .signature .clone() .try_into() .map_err(|_| anyhow!("sth signature must be 64 bytes"))?, @@ -1307,14 +1313,15 @@ async fn main() -> anyhow::Result<()> { persist_sth_cache(&cache_path, &cache)?; - serde_json::json!({"capsule_len": resp.capsule.len(), "inclusion_ok": inclusion_ok, "consistency_ok": consistency_ok}) + serde_json::json!({"capsule_len": resp.capsule_bytes.len(), "inclusion_ok": inclusion_ok, "consistency_ok": consistency_ok}) } else { - serde_json::json!({"capsule_len": resp.capsule.len(), "etl_index": resp.etl_index}) + serde_json::json!({"capsule_len": resp.capsule_bytes.len(), "etl_index": resp.etl_index}) }; - if print_capsule_json { - let capsule_json: serde_json::Value = serde_json::from_slice(&resp.capsule) - .context("capsule is not valid json")?; + if *print_capsule_json { + let capsule_json: serde_json::Value = + serde_json::from_slice(&resp.capsule_bytes) + .context("capsule is not valid json")?; output["capsule_summary"] = build_capsule_print_summary(&capsule_json); } @@ -1347,10 +1354,12 @@ async fn main() -> anyhow::Result<()> { .await?; while let Some(ev) = stream.next().await { let ev = ev?; - println!( - "{}", - serde_json::json!({"claim_id": hex_encode(&ev.claim_id), "reason_code": ev.reason_code, "logical_epoch": ev.logical_epoch}) - ); + for entry in ev.entries { + println!( + "{}", + serde_json::json!({"claim_id": hex_encode(&entry.claim_id), "reason": entry.reason, "timestamp_unix": entry.timestamp_unix}) + ); + } } } }