Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: read_vec_raw target visibility, add common errors about new toolchain #1939

Merged
merged 6 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/book.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ name: book

on:
push:
branches: [main]
branches: [dev]
pull_request:
branches: [main]
branches: [dev]
paths:
- "book/**"
merge_group:
Expand Down Expand Up @@ -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]

Expand Down
19 changes: 18 additions & 1 deletion .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -371,4 +371,21 @@ jobs:
- name: "Build examples without lock files"
run: |
cd examples
cargo build --all --all-targets
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
20 changes: 19 additions & 1 deletion book/docs/developers/common-issues.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,22 @@ To resolve this, ensure that you're importing both `sp1-lib` and `sp1-zkvm` with
[dependencies]
sp1-lib = { version = "<VERSION>", features = ["verify"] }
sp1-zkvm = { version = "<VERSION>", features = ["verify"] }
```
```

## 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.

2 changes: 2 additions & 0 deletions book/docs/developers/usage-in-ci.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 <commit>`.

## Speeding up your CI workflow

### Caching
Expand Down
20 changes: 19 additions & 1 deletion book/versioned_docs/version-4.0.0/developers/common-issues.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,22 @@ To resolve this, ensure that you're importing both `sp1-lib` and `sp1-zkvm` with
[dependencies]
sp1-lib = { version = "<VERSION>", features = ["verify"] }
sp1-zkvm = { version = "<VERSION>", features = ["verify"] }
```
```

## 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.

2 changes: 2 additions & 0 deletions book/versioned_docs/version-4.0.0/developers/usage-in-ci.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 <commit>`.

## Speeding up your CI workflow

### Caching
Expand Down
2 changes: 2 additions & 0 deletions crates/build/src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
5 changes: 2 additions & 3 deletions crates/zkvm/entrypoint/src/allocators/bump.rs
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down
6 changes: 3 additions & 3 deletions crates/zkvm/entrypoint/src/allocators/embedded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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 {
Expand Down
5 changes: 4 additions & 1 deletion crates/zkvm/entrypoint/src/allocators/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@
mod bump;

#[cfg(feature = "embedded")]
pub mod embedded;
mod embedded;

#[cfg(feature = "embedded")]
pub use embedded::{free, init, used};
117 changes: 62 additions & 55 deletions crates/zkvm/entrypoint/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand Down Expand Up @@ -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,
Expand All @@ -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.");
}
}
}
Expand All @@ -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")]
Expand Down
2 changes: 2 additions & 0 deletions patch-testing/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions patch-testing/build-host/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
7 changes: 7 additions & 0 deletions patch-testing/build-host/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Loading