diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..7c2d11f --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,48 @@ +name: CI + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + # Disable Lint + + # Lint: + # runs-on: ubuntu-latest + + # steps: + # - uses: actions/checkout@v4 + # - name: Install stable Rust + # uses: actions-rs/toolchain@v1 + # with: + # toolchain: stable + # components: rustfmt, clippy + + # - name: Fmt + # run: cargo fmt --check + + # - name: Clippy + # run: cargo clippy -- -D warnings + + Test: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: Install stable Rust + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + components: clippy + + - name: Run e2e test + run: ./scripts/e2e_test.sh + + - name: Run unit tests + run: cargo test --release --all-features -- --nocapture diff --git a/.gitignore b/.gitignore index 4e0d6e4..20fd7be 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ Cargo.lock vm_run_output.log *.bin .DS_Store -*.log \ No newline at end of file +*.log +build/ceno diff --git a/scripts/e2e_test.sh b/scripts/e2e_test.sh new file mode 100755 index 0000000..65b6e1e --- /dev/null +++ b/scripts/e2e_test.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(git -C "$SCRIPT_DIR" rev-parse --show-toplevel)" + +# Clone the ceno repository if it doesn't exist +if [ ! -d "$REPO_ROOT/build/ceno" ] || [ -z "$(ls -A "$REPO_ROOT/build/ceno" 2>/dev/null)" ]; then + git clone https://github.com/scroll-tech/ceno.git "$REPO_ROOT/build/ceno/" +fi + +# Enter the ceno directory +cd $REPO_ROOT/build/ceno && git checkout build/smaller_field_support_plonky3_539bbc + +# Execute the ceno_zkvm e2e test +RUST_LOG=info cargo run --release --package ceno_zkvm --bin e2e -- --platform=ceno \ + --hints=10 --public-io=4191 examples/target/riscv32im-ceno-zkvm-elf/release/examples/fibonacci \ + --field=baby-bear + +mkdir -p $REPO_ROOT/src/e2e/encoded + +# Copy vk.bin and proof.bin to the src/e2e/encoded directory in the parent directory +cp vk.bin $REPO_ROOT/src/e2e/encoded/ +cp proof.bin $REPO_ROOT/src/e2e/encoded/ + +# Return to the root directory +cd $REPO_ROOT + +# Execute the test_zkvm_proof_verifier test +RUST_LOG=info cargo test --release --lib test_zkvm_proof_verifier -- --nocapture diff --git a/src/e2e/mod.rs b/src/e2e/mod.rs index b707d72..ee671a0 100644 --- a/src/e2e/mod.rs +++ b/src/e2e/mod.rs @@ -9,6 +9,7 @@ use ff_ext::BabyBearExt4; use itertools::Itertools; use mpcs::{Basefold, BasefoldRSParams}; use openvm_circuit::arch::{instructions::program::Program, SystemConfig, VmExecutor}; +use openvm_circuit::arch::{verify_single, VirtualMachine}; use openvm_native_circuit::{Native, NativeConfig}; use openvm_native_compiler::{ asm::AsmBuilder, @@ -17,7 +18,10 @@ use openvm_native_compiler::{ }; use openvm_native_recursion::hints::Hintable; use openvm_stark_backend::config::StarkGenericConfig; -use openvm_stark_sdk::config::setup_tracing_with_log_level; +use openvm_stark_sdk::config::baby_bear_poseidon2::BabyBearPoseidon2Engine; +use openvm_stark_sdk::config::fri_params::standard_fri_params_with_100_bits_conjectured_security; +use openvm_stark_sdk::config::{setup_tracing_with_log_level, FriParameters}; +use openvm_stark_sdk::engine::StarkFriEngine; use openvm_stark_sdk::{ config::baby_bear_poseidon2::BabyBearPoseidon2Config, p3_baby_bear::BabyBear, }; @@ -259,9 +263,7 @@ pub fn inner_test_thread() { return (); */ - let program: Program< - p3_monty_31::MontyField31, - > = convert_program(asm_code, options); + let program: Program = convert_program(asm_code, options); let mut system_config = SystemConfig::default() .with_public_values(4) .with_max_segment_len((1 << 25) - 100); @@ -271,12 +273,45 @@ pub fn inner_test_thread() { let executor = VmExecutor::::new(config); let res = executor - .execute_and_then(program, witness_stream, |_, seg| Ok(seg), |err| err) + .execute_and_then( + program.clone(), + witness_stream.clone(), + |_, seg| Ok(seg), + |err| err, + ) .unwrap(); for (i, seg) in res.iter().enumerate() { println!("=> segment {:?} metrics: {:?}", i, seg.metrics); } + + let poseidon2_max_constraint_degree = 3; + // TODO: use log_blowup = 1 when native multi_observe chip reduces max constraint degree to 3 + let log_blowup = 2; + + let fri_params = if matches!(std::env::var("OPENVM_FAST_TEST"), Ok(x) if &x == "1") { + FriParameters { + log_blowup, + log_final_poly_len: 0, + num_queries: 10, + proof_of_work_bits: 0, + } + } else { + standard_fri_params_with_100_bits_conjectured_security(log_blowup) + }; + + let engine = BabyBearPoseidon2Engine::new(fri_params); + let mut config = NativeConfig::aggregation(0, poseidon2_max_constraint_degree); + config.system.memory_config.max_access_adapter_n = 16; + + let vm = VirtualMachine::new(engine, config); + + let pk = vm.keygen(); + let result = vm.execute_and_generate(program, witness_stream).unwrap(); + let proofs = vm.prove(&pk, result); + for proof in proofs { + verify_single(&vm.engine, &pk.get_vk(), &proof).expect("Verification failed"); + } } #[test]