diff --git a/.github/workflows/book.yml b/.github/workflows/book.yml index 8d2529e8d..86eab9883 100644 --- a/.github/workflows/book.yml +++ b/.github/workflows/book.yml @@ -5,9 +5,9 @@ name: book on: push: - branches: [main] + branches: [dev] pull_request: - branches: [main] + branches: [dev] paths: - "book/**" merge_group: @@ -46,7 +46,7 @@ jobs: deploy: # Only deploy if a push to main - if: github.ref_name == 'main' && github.event_name == 'push' + if: github.ref_name == 'dev' && github.event_name == 'push' runs-on: ubuntu-latest needs: [build] diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index c7ec27262..6b210fcfd 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -371,4 +371,21 @@ jobs: - name: "Build examples without lock files" run: | cd examples - cargo build --all --all-targets \ No newline at end of file + cargo build --all --all-targets + + build-in-host: + name: "Build patches and zkvm in host" + runs-on: [runs-on, runner=16cpu-linux-x64, disk=large, "run-id=${{ github.run_id }}"] + steps: + - name: "Checkout sources" + uses: "actions/checkout@v4" + + - name: "Setup CI" + uses: ./.github/actions/setup + with: + pull_token: ${{ secrets.PRIVATE_PULL_TOKEN }} + + - name: "Build programs in host" + run: | + cd ./patch-testing/build-host + cargo build \ No newline at end of file diff --git a/book/docs/developers/common-issues.md b/book/docs/developers/common-issues.md index 7bb6fb79d..8d027499c 100644 --- a/book/docs/developers/common-issues.md +++ b/book/docs/developers/common-issues.md @@ -120,4 +120,22 @@ To resolve this, ensure that you're importing both `sp1-lib` and `sp1-zkvm` with [dependencies] sp1-lib = { version = "", features = ["verify"] } sp1-zkvm = { version = "", features = ["verify"] } -``` \ No newline at end of file +``` + +## Failed to run LLVM passes: unknown pass name 'loweratomic' + +The Rust compiler had breaking changes to its names of available options between 1.81 and 1.82. + +```bash + [sp1] Compiling proc-macro2 v1.0.93 + [sp1] Compiling unicode-ident v1.0.14 + [sp1] Compiling quote v1.0.38 + [sp1] Compiling syn v2.0.96 + [sp1] Compiling serde_derive v1.0.217 + [sp1] Compiling serde v1.0.217 + [sp1] error: failed to run LLVM passes: unknown pass name 'loweratomic' +``` + +This message indicates that you're trying to use `sp1-build` < `4.0.0` with the 1.82 toolchain, +`sp1-build` versions >= 4.0.0 have support for the 1.82 and 1.81 toolchains. + diff --git a/book/docs/developers/usage-in-ci.md b/book/docs/developers/usage-in-ci.md index ac4b1ba3c..7bb69c80b 100644 --- a/book/docs/developers/usage-in-ci.md +++ b/book/docs/developers/usage-in-ci.md @@ -41,6 +41,8 @@ Try setting a github actions secret to your PAT, and then passing it into the `s ~/.sp1/bin/cargo-prove prove --version ``` +Note: Installing via `sp1up` always installs the latest version, its recommended to [use a release commit](https://github.com/succinctlabs/sp1/releases) via `sp1up -C `. + ## Speeding up your CI workflow ### Caching diff --git a/book/versioned_docs/version-4.0.0/developers/common-issues.md b/book/versioned_docs/version-4.0.0/developers/common-issues.md index 7bb6fb79d..8d027499c 100644 --- a/book/versioned_docs/version-4.0.0/developers/common-issues.md +++ b/book/versioned_docs/version-4.0.0/developers/common-issues.md @@ -120,4 +120,22 @@ To resolve this, ensure that you're importing both `sp1-lib` and `sp1-zkvm` with [dependencies] sp1-lib = { version = "", features = ["verify"] } sp1-zkvm = { version = "", features = ["verify"] } -``` \ No newline at end of file +``` + +## Failed to run LLVM passes: unknown pass name 'loweratomic' + +The Rust compiler had breaking changes to its names of available options between 1.81 and 1.82. + +```bash + [sp1] Compiling proc-macro2 v1.0.93 + [sp1] Compiling unicode-ident v1.0.14 + [sp1] Compiling quote v1.0.38 + [sp1] Compiling syn v2.0.96 + [sp1] Compiling serde_derive v1.0.217 + [sp1] Compiling serde v1.0.217 + [sp1] error: failed to run LLVM passes: unknown pass name 'loweratomic' +``` + +This message indicates that you're trying to use `sp1-build` < `4.0.0` with the 1.82 toolchain, +`sp1-build` versions >= 4.0.0 have support for the 1.82 and 1.81 toolchains. + diff --git a/book/versioned_docs/version-4.0.0/developers/usage-in-ci.md b/book/versioned_docs/version-4.0.0/developers/usage-in-ci.md index ac4b1ba3c..7bb69c80b 100644 --- a/book/versioned_docs/version-4.0.0/developers/usage-in-ci.md +++ b/book/versioned_docs/version-4.0.0/developers/usage-in-ci.md @@ -41,6 +41,8 @@ Try setting a github actions secret to your PAT, and then passing it into the `s ~/.sp1/bin/cargo-prove prove --version ``` +Note: Installing via `sp1up` always installs the latest version, its recommended to [use a release commit](https://github.com/succinctlabs/sp1/releases) via `sp1up -C `. + ## Speeding up your CI workflow ### Caching diff --git a/crates/build/src/build.rs b/crates/build/src/build.rs index 35f837345..e48e8129e 100644 --- a/crates/build/src/build.rs +++ b/crates/build/src/build.rs @@ -72,6 +72,8 @@ pub fn execute_build_program( std::fs::copy(&elf_path, &output_path)?; } + } else if args.elf_name.is_some() { + println!("cargo:warning=ELF name is set but --output-directory is not used"); } print_elf_paths_cargo_directives(&target_elf_paths); diff --git a/crates/zkvm/entrypoint/src/allocators/bump.rs b/crates/zkvm/entrypoint/src/allocators/bump.rs index 4e38ad5c7..402c7db93 100644 --- a/crates/zkvm/entrypoint/src/allocators/bump.rs +++ b/crates/zkvm/entrypoint/src/allocators/bump.rs @@ -1,11 +1,10 @@ -use core::alloc::{GlobalAlloc, Layout}; - use crate::syscalls::sys_alloc_aligned; +use core::alloc::{GlobalAlloc, Layout}; /// A simple heap allocator. /// /// Allocates memory from left to right, without any deallocation. -pub struct SimpleAlloc; +struct SimpleAlloc; unsafe impl GlobalAlloc for SimpleAlloc { unsafe fn alloc(&self, layout: Layout) -> *mut u8 { diff --git a/crates/zkvm/entrypoint/src/allocators/embedded.rs b/crates/zkvm/entrypoint/src/allocators/embedded.rs index a4d493407..bed38bc9e 100644 --- a/crates/zkvm/entrypoint/src/allocators/embedded.rs +++ b/crates/zkvm/entrypoint/src/allocators/embedded.rs @@ -6,9 +6,9 @@ use critical_section::RawRestoreState; use embedded_alloc::LlffHeap as Heap; #[global_allocator] -pub static HEAP: EmbeddedAlloc = EmbeddedAlloc; +static HEAP: EmbeddedAlloc = EmbeddedAlloc; -pub static INNER_HEAP: Heap = Heap::empty(); +static INNER_HEAP: Heap = Heap::empty(); struct CriticalSection; critical_section::set_impl!(CriticalSection); @@ -39,7 +39,7 @@ pub fn free() -> usize { critical_section::with(|cs| INNER_HEAP.free()) } -pub struct EmbeddedAlloc; +struct EmbeddedAlloc; unsafe impl GlobalAlloc for EmbeddedAlloc { unsafe fn alloc(&self, layout: Layout) -> *mut u8 { diff --git a/crates/zkvm/entrypoint/src/allocators/mod.rs b/crates/zkvm/entrypoint/src/allocators/mod.rs index 67150d967..86fca0591 100644 --- a/crates/zkvm/entrypoint/src/allocators/mod.rs +++ b/crates/zkvm/entrypoint/src/allocators/mod.rs @@ -6,4 +6,7 @@ mod bump; #[cfg(feature = "embedded")] -pub mod embedded; +mod embedded; + +#[cfg(feature = "embedded")] +pub use embedded::{free, init, used}; diff --git a/crates/zkvm/entrypoint/src/lib.rs b/crates/zkvm/entrypoint/src/lib.rs index 4b0f9ae76..1d73c67ec 100644 --- a/crates/zkvm/entrypoint/src/lib.rs +++ b/crates/zkvm/entrypoint/src/lib.rs @@ -1,11 +1,11 @@ #[cfg(all(target_os = "zkvm", feature = "embedded"))] -pub use syscalls::MAX_MEMORY; +use syscalls::MAX_MEMORY; #[cfg(target_os = "zkvm")] -use cfg_if::cfg_if; - -#[cfg(target_os = "zkvm")] -use syscalls::{syscall_hint_len, syscall_hint_read}; +use { + cfg_if::cfg_if, + syscalls::{syscall_hint_len, syscall_hint_read}, +}; extern crate alloc; @@ -33,16 +33,18 @@ pub const POSEIDON_NUM_WORDS: usize = 8; /// Size of the reserved region for input values with the embedded allocator. #[cfg(all(target_os = "zkvm", feature = "embedded"))] -pub const EMBEDDED_RESERVED_INPUT_REGION_SIZE: usize = 1024 * 1024 * 1024; +pub(crate) const EMBEDDED_RESERVED_INPUT_REGION_SIZE: usize = 1024 * 1024 * 1024; + /// Start of the reserved region for inputs with the embedded allocator. #[cfg(all(target_os = "zkvm", feature = "embedded"))] -pub const EMBEDDED_RESERVED_INPUT_START: usize = MAX_MEMORY - EMBEDDED_RESERVED_INPUT_REGION_SIZE; +pub(crate) const EMBEDDED_RESERVED_INPUT_START: usize = + MAX_MEMORY - EMBEDDED_RESERVED_INPUT_REGION_SIZE; + /// Pointer to the current position in the reserved region for inputs with the embedded allocator. #[cfg(all(target_os = "zkvm", feature = "embedded"))] static mut EMBEDDED_RESERVED_INPUT_PTR: usize = EMBEDDED_RESERVED_INPUT_START; #[repr(C)] -#[cfg(target_os = "zkvm")] pub struct ReadVecResult { pub ptr: *mut u8, pub len: usize, @@ -60,57 +62,62 @@ pub struct ReadVecResult { /// /// When there is no allocator selected, the program will fail to compile. #[no_mangle] -#[cfg(target_os = "zkvm")] pub extern "C" fn read_vec_raw() -> ReadVecResult { - // Get the length of the input buffer. - let len = syscall_hint_len(); - // Round up to multiple of 4 for whole-word alignment. - let capacity = (len + 3) / 4 * 4; - - cfg_if! { - if #[cfg(feature = "embedded")] { - // Get the existing pointer in the reserved region which is the start of the vec. - // Increment the pointer by the capacity to set the new pointer to the end of the vec. - let ptr = unsafe { EMBEDDED_RESERVED_INPUT_PTR }; - if ptr + capacity > MAX_MEMORY { - panic!("Input region overflowed.") - } + #[cfg(not(target_os = "zkvm"))] + unreachable!("read_vec_raw should only be called on the zkvm target."); + + #[cfg(target_os = "zkvm")] + { + // Get the length of the input buffer. + let len = syscall_hint_len(); + // Round up to multiple of 4 for whole-word alignment. + let capacity = (len + 3) / 4 * 4; + + cfg_if! { + if #[cfg(feature = "embedded")] { + // Get the existing pointer in the reserved region which is the start of the vec. + // Increment the pointer by the capacity to set the new pointer to the end of the vec. + let ptr = unsafe { EMBEDDED_RESERVED_INPUT_PTR }; + if ptr + capacity > MAX_MEMORY { + panic!("Input region overflowed.") + } - // SAFETY: The VM is single threaded. - unsafe { EMBEDDED_RESERVED_INPUT_PTR += capacity }; + // SAFETY: The VM is single threaded. + unsafe { EMBEDDED_RESERVED_INPUT_PTR += capacity }; - // Read the vec into uninitialized memory. The syscall assumes the memory is - // uninitialized, which is true because the input ptr is incremented manually on each - // read. - syscall_hint_read(ptr as *mut u8, len); + // Read the vec into uninitialized memory. The syscall assumes the memory is + // uninitialized, which is true because the input ptr is incremented manually on each + // read. + syscall_hint_read(ptr as *mut u8, len); - // Return the result. - ReadVecResult { - ptr: ptr as *mut u8, - len, - capacity, - } - } else if #[cfg(feature = "bump")] { - // Allocate a buffer of the required length that is 4 byte aligned. - let layout = std::alloc::Layout::from_size_align(capacity, 4).expect("vec is too large"); - - // SAFETY: The layout was made through the checked constructor. - let ptr = unsafe { std::alloc::alloc(layout) }; - - // Read the vec into uninitialized memory. The syscall assumes the memory is - // uninitialized, which is true because the bump allocator does not dealloc, so a new - // alloc is always fresh. - syscall_hint_read(ptr as *mut u8, len); - - // Return the result. - ReadVecResult { - ptr: ptr as *mut u8, - len, - capacity, + // Return the result. + ReadVecResult { + ptr: ptr as *mut u8, + len, + capacity, + } + } else if #[cfg(feature = "bump")] { + // Allocate a buffer of the required length that is 4 byte aligned. + let layout = std::alloc::Layout::from_size_align(capacity, 4).expect("vec is too large"); + + // SAFETY: The layout was made through the checked constructor. + let ptr = unsafe { std::alloc::alloc(layout) }; + + // Read the vec into uninitialized memory. The syscall assumes the memory is + // uninitialized, which is true because the bump allocator does not dealloc, so a new + // alloc is always fresh. + syscall_hint_read(ptr as *mut u8, len); + + // Return the result. + ReadVecResult { + ptr: ptr as *mut u8, + len, + capacity, + } + } else { + // An allocator must be selected. + compile_error!("There is no allocator selected. Please enable the `bump` or `embedded` feature."); } - } else { - // An allocator must be selected. - compile_error!("There is no allocator selected. Please enable the `bump` or `embedded` feature."); } } } @@ -137,7 +144,7 @@ mod zkvm { unsafe extern "C" fn __start() { { #[cfg(all(target_os = "zkvm", feature = "embedded"))] - crate::allocators::embedded::init(); + crate::allocators::init(); PUBLIC_VALUES_HASHER = Some(Sha256::new()); #[cfg(feature = "verify")] diff --git a/patch-testing/Cargo.lock b/patch-testing/Cargo.lock index a1968ed53..1538c0391 100644 --- a/patch-testing/Cargo.lock +++ b/patch-testing/Cargo.lock @@ -481,6 +481,8 @@ dependencies = [ "sha2 0.10.6", "sha2 0.10.8 (git+https://github.com/sp1-patches/RustCrypto-hashes?tag=patch-sha2-0.10.8-sp1-4.0.0)", "sha3 0.10.8", + "sp1-lib", + "sp1-zkvm", "substrate-bn 0.6.0 (git+https://github.com/sp1-patches/bn?tag=patch-0.6.0-sp1-4.0.0)", "tiny-keccak 2.0.2 (git+https://github.com/sp1-patches/tiny-keccak?tag=patch-2.0.2-sp1-4.0.0)", ] diff --git a/patch-testing/build-host/Cargo.toml b/patch-testing/build-host/Cargo.toml index 8d1b29783..b6d59ddc8 100644 --- a/patch-testing/build-host/Cargo.toml +++ b/patch-testing/build-host/Cargo.toml @@ -17,3 +17,5 @@ secp256k1-patched = { workspace = true } substrate-bn-patched = { workspace = true } bls12_381-patched = { workspace = true } rsa-patched = { workspace = true } +sp1-lib = { path = "../../crates/zkvm/lib" } +sp1-zkvm = { path = "../../crates/zkvm/entrypoint" } \ No newline at end of file diff --git a/patch-testing/build-host/src/main.rs b/patch-testing/build-host/src/main.rs index 1113c3a2b..935e4dea3 100644 --- a/patch-testing/build-host/src/main.rs +++ b/patch-testing/build-host/src/main.rs @@ -8,9 +8,16 @@ pub use secp256k1_patched; pub use sha2_v0_10_6_patched; pub use sha2_v0_10_8_patched; pub use sha3_v0_10_8_patched; +pub use sp1_lib; +pub use sp1_zkvm; pub use substrate_bn_patched; pub use tiny_keccak_patched; fn main() { // Note: This file is a dummy that merely imports all the patches, to ensure that they build correctly outside our vm. + read_vec_in_host(); +} + +fn read_vec_in_host() { + sp1_lib::io::read_vec(); }