From d9507aa2ac736eeb0300916b41bfc616073a9f12 Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Fri, 8 Nov 2024 13:45:30 -0800 Subject: [PATCH] ci: automatically lint and build CLI (#33) --- .github/workflows/ci.yml | 64 +++++++++++++++++++++++++++++ clients/cli/Cargo.lock | 2 +- clients/cli/Cargo.toml | 24 ++++++++--- clients/cli/src/analytics.rs | 2 +- clients/cli/src/config.rs | 2 +- clients/cli/src/prover.rs | 80 +++++++++++++++++++++--------------- proto/generate_protobufs.sh | 8 ---- 7 files changed, 131 insertions(+), 51 deletions(-) create mode 100644 .github/workflows/ci.yml delete mode 100755 proto/generate_protobufs.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..1e1bf48 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,64 @@ +name: ci + +on: + push: + branches: + - main + pull_request: + branches: + - "**" + +jobs: + build: + name: Lint CLI + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + sparse-checkout: | + clients/cli + proto + + - name: Set up Rust + uses: dtolnay/rust-toolchain@stable + + - name: Install protoc + uses: arduino/setup-protoc@v3 + + - name: Set up Rust cache + uses: Swatinem/rust-cache@v2 + with: + workspaces: ./clients/cli + + - name: Format + working-directory: clients/cli + run: | + rustfmt src/**/*.rs --check --edition 2021 + + - name: Build + working-directory: clients/cli + run: | + cargo build --profile=ci-build + + - name: Run cargo clippy + working-directory: clients/cli + run: | + cargo clippy --profile=ci-build --no-deps --all-targets --workspace -- -D warnings + + - name: Test + working-directory: clients/cli + run: | + cargo test --profile=ci-build --tests + + - name: Ensure checked in generated files are up to date + run: | + if [ -n "$(git status --porcelain)" ]; then \ + echo "There are uncommitted changes in working tree after building."; \ + git status; \ + git --no-pager diff; \ + exit 1; \ + else \ + echo "Git working tree is clean"; \ + fi; diff --git a/clients/cli/Cargo.lock b/clients/cli/Cargo.lock index 54b14b2..53b9465 100644 --- a/clients/cli/Cargo.lock +++ b/clients/cli/Cargo.lock @@ -1567,7 +1567,7 @@ dependencies = [ [[package]] name = "nexus-network" -version = "0.1.0" +version = "0.3.4" dependencies = [ "ark-bn254", "ark-crypto-primitives", diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index cee2b7c..383b485 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nexus-network" -version = "0.3.2" +version = "0.3.4" edition = "2021" [[bin]] @@ -10,6 +10,23 @@ path = "src/prover.rs" [build-dependencies] prost-build = "0.13" +[profile.dev] +opt-level = 1 + +[profile.release] +lto = "fat" +strip = true +codegen-units = 1 + +[profile.ci-build] +inherits = "dev" +opt-level = 0 +debug = 0 +strip = "none" +lto = false +codegen-units = 256 +incremental = true + [dependencies] async-stream = "0.3" clap = { version = "4.5", features = ["derive"] } @@ -83,8 +100,3 @@ ark-vesta = { git = "https://github.com/arkworks-rs/curves/", rev = "8c0256a" } ark-bls12-381 = { git = "https://github.com/arkworks-rs/curves/", rev = "3fded1f" } zstd-sys = { git = "https://github.com/gyscos/zstd-rs" } - -[profile.release] -strip = true -lto = true -codegen-units = 1 diff --git a/clients/cli/src/analytics.rs b/clients/cli/src/analytics.rs index 190f180..effd2ee 100644 --- a/clients/cli/src/analytics.rs +++ b/clients/cli/src/analytics.rs @@ -44,7 +44,7 @@ pub fn track( let client = reqwest::Client::new(); let _ = client .post("https://api.mixpanel.com/track?ip=1") - .body(format!("[{}]", body.to_string())) + .body(format!("[{}]", body)) .header(ACCEPT, "text/plain") .header(CONTENT_TYPE, "application/json") .send() diff --git a/clients/cli/src/config.rs b/clients/cli/src/config.rs index 042ab71..50a7f5f 100644 --- a/clients/cli/src/config.rs +++ b/clients/cli/src/config.rs @@ -1,7 +1,7 @@ #[cfg(debug_assertions)] pub fn analytics_token(_ws_addr_string: &str) -> String { // Use one of the tokens in the release version if debugging analytics - return "".into(); + "".into() } #[cfg(not(debug_assertions))] diff --git a/clients/cli/src/prover.rs b/clients/cli/src/prover.rs index a9efff7..40a2be4 100644 --- a/clients/cli/src/prover.rs +++ b/clients/cli/src/prover.rs @@ -32,8 +32,8 @@ use nexus_core::{ init_circuit_trace, key::CanonicalSerialize, pp::gen_vm_pp, prove_seq_step, types::*, }, }; +use rand::RngCore; use zstd::stream::Encoder; -use rand::{ RngCore }; #[derive(Parser, Debug)] struct Args { @@ -118,7 +118,7 @@ async fn main() { contents: Some(prover_request::Contents::Registration( ProverRequestRegistration { prover_type: ProverType::Volunteer.into(), - prover_id: prover_id.clone().into(), + prover_id: prover_id.clone(), estimated_proof_cycles_hertz: None, }, )), @@ -127,21 +127,25 @@ async fn main() { let mut retries = 0; let max_retries = 5; - loop { - if let Err(e) = client.send(Message::Binary(registration.encode_to_vec())).await { - eprintln!("Failed to send message: {:?}, attempt {}/{}", e, retries + 1, max_retries); + while let Err(e) = client + .send(Message::Binary(registration.encode_to_vec())) + .await + { + eprintln!( + "Failed to send message: {:?}, attempt {}/{}", + e, + retries + 1, + max_retries + ); - retries += 1; - if retries >= max_retries { - eprintln!("Max retries reached, exiting..."); - break; - } - - // Add a delay before retrying - tokio::time::sleep(tokio::time::Duration::from_secs(u64::pow(2, retries))).await; - } else { + retries += 1; + if retries >= max_retries { + eprintln!("Max retries reached, exiting..."); break; } + + // Add a delay before retrying + tokio::time::sleep(tokio::time::Duration::from_secs(u64::pow(2, retries))).await; } track( @@ -180,7 +184,7 @@ async fn main() { ); let mut vm: NexusVM = - parse_elf(&elf_bytes.as_ref()).expect("error loading and parsing RISC-V instruction"); + parse_elf(elf_bytes.as_ref()).expect("error loading and parsing RISC-V instruction"); vm.syscalls.set_input(&input); // TODO(collinjackson): Get outputs @@ -244,10 +248,10 @@ async fn main() { completed_fraction = steps_proven as f32 / steps_to_prove as f32; let progress = ProverRequest { contents: Some(prover_request::Contents::Progress(Progress { - completed_fraction: completed_fraction, + completed_fraction, steps_in_trace: total_steps as i32, steps_to_prove: steps_to_prove as i32, - steps_proven: steps_proven as i32, + steps_proven, })), }; let progress_duration = SystemTime::now().duration_since(progress_time).unwrap(); @@ -255,7 +259,10 @@ async fn main() { let proof_cycles_hertz = k as f64 * 1000.0 / progress_duration.as_millis() as f64; track( "progress".into(), - format!("Proved step {} at {:.2} proof cycles/sec.", step, proof_cycles_hertz), + format!( + "Proved step {} at {:.2} proof cycles/sec.", + step, proof_cycles_hertz + ), &ws_addr_string, json!({ "completed_fraction": completed_fraction, @@ -273,21 +280,22 @@ async fn main() { let mut retries = 0; let max_retries = 5; - loop { - if let Err(e) = client.send(Message::Binary(progress.encode_to_vec())).await { - eprintln!("Failed to send message: {:?}, attempt {}/{}", e, retries + 1, max_retries); - - retries += 1; - if retries >= max_retries { - eprintln!("Max retries reached, exiting..."); - break; - } - - // Add a delay before retrying - tokio::time::sleep(tokio::time::Duration::from_secs(u64::pow(2, retries))).await; - } else { + while let Err(e) = client.send(Message::Binary(progress.encode_to_vec())).await { + eprintln!( + "Failed to send message: {:?}, attempt {}/{}", + e, + retries + 1, + max_retries + ); + + retries += 1; + if retries >= max_retries { + eprintln!("Max retries reached, exiting..."); break; } + + // Add a delay before retrying + tokio::time::sleep(tokio::time::Duration::from_secs(u64::pow(2, retries))).await; } if step == end - 1 { @@ -305,14 +313,18 @@ async fn main() { })), }; let duration = SystemTime::now().duration_since(start_time).unwrap(); - let proof_cycles_hertz = cycles_proven as f64 * 1000.0 / duration.as_millis() as f64; + let proof_cycles_hertz = + cycles_proven as f64 * 1000.0 / duration.as_millis() as f64; client .send(Message::Binary(response.encode_to_vec())) .await - .unwrap(); + .unwrap(); track( "proof".into(), - format!("Proof sent! Overall speed was {:.2} proof cycles/sec.", proof_cycles_hertz), + format!( + "Proof sent! Overall speed was {:.2} proof cycles/sec.", + proof_cycles_hertz + ), &ws_addr_string, json!({ "proof_duration_sec": duration.as_secs(), diff --git a/proto/generate_protobufs.sh b/proto/generate_protobufs.sh deleted file mode 100755 index a8015ca..0000000 --- a/proto/generate_protobufs.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -mkdir -p clients/flutter/lib/src/generated -protoc --experimental_allow_proto3_optional --dart_out=grpc:clients/flutter/lib/src/generated -Iproto proto/orchestrator.proto -dart format clients/flutter/lib/src/generated -(cd clients/dummy_client && cargo build || echo clients/dummy_client not found, possibly due to a sparse checkout.) -(cd clients/cli && cargo build || echo clients/cli not found, possibly due to a sparse checkout.) -(cd orchestrator && cargo build || echo orchestrator/ not found, possibly due a sparse checkout.)