mirror of
https://github.com/eth-act/ere.git
synced 2026-04-03 03:00:17 -04:00
Add ere-dockerized (#75)
This commit is contained in:
16
docker/cli/Dockerfile
Normal file
16
docker/cli/Dockerfile
Normal file
@@ -0,0 +1,16 @@
|
||||
ARG BASE_ZKVM_IMAGE_TAG=ere-base-zkvm:latest
|
||||
|
||||
FROM ${BASE_ZKVM_IMAGE_TAG}
|
||||
|
||||
COPY . /ere
|
||||
|
||||
WORKDIR /ere
|
||||
|
||||
ARG ZKVM
|
||||
|
||||
RUN cargo build --release --package ere-cli --bin ere-cli --features ${ZKVM} && \
|
||||
cp /ere/target/release/ere-cli /ere/ere-cli && \
|
||||
cargo clean && \
|
||||
rm -rf $CARGO_HOME/registry/src $CARGO_HOME/registry/cache
|
||||
|
||||
ENTRYPOINT ["/ere/ere-cli"]
|
||||
@@ -1,5 +1,6 @@
|
||||
ARG BASE_IMAGE_TAG=latest
|
||||
FROM ere-base:${BASE_IMAGE_TAG}
|
||||
ARG BASE_IMAGE_TAG=ere-base:latest
|
||||
|
||||
FROM ${BASE_IMAGE_TAG}
|
||||
|
||||
# The ere-base image provides Rust, Cargo (with a default nightly), and common tools.
|
||||
# We operate as root for SDK installation.
|
||||
@@ -17,4 +18,4 @@ RUN /tmp/install_jolt_sdk.sh && rm /tmp/install_jolt_sdk.sh # Clean up the scrip
|
||||
# Verify jolt CLI is accessible.
|
||||
RUN jolt --version
|
||||
|
||||
CMD ["/bin/bash"]
|
||||
CMD ["/bin/bash"]
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
ARG BASE_IMAGE_TAG=latest
|
||||
FROM ere-base:${BASE_IMAGE_TAG}
|
||||
ARG BASE_IMAGE_TAG=ere-base:latest
|
||||
|
||||
FROM ${BASE_IMAGE_TAG}
|
||||
|
||||
# The ere-base image provides Rust, Cargo, and common tools.
|
||||
# We operate as root for SDK installation.
|
||||
@@ -20,21 +21,10 @@ RUN /tmp/install_nexus_sdk.sh && rm /tmp/install_nexus_sdk.sh # Clean up the scr
|
||||
# Define the Nexus toolchain for convenience in subsequent commands if needed, though cargo-nexus should use it.
|
||||
ENV NEXUS_TOOLCHAIN_VERSION="nightly-2025-06-05"
|
||||
|
||||
# Set default toolchain
|
||||
RUN rustup default "$NEXUS_TOOLCHAIN_VERSION"
|
||||
|
||||
# Verify Nexus installation
|
||||
RUN echo "Verifying Nexus installation in Dockerfile (post-script)..." && cargo-nexus --version
|
||||
|
||||
# Copy the entire ere project context
|
||||
# The WORKDIR is /app from the base image
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
|
||||
# Build
|
||||
RUN echo "Build tests for ere-nexus library..." && \
|
||||
cargo build --tests --release -p ere-nexus
|
||||
|
||||
# Run tests
|
||||
RUN echo "Running tests for ere-nexus library..." && \
|
||||
cargo test --release -p ere-nexus --lib -- --color always && \
|
||||
echo "Running Nexus tests Success..."
|
||||
|
||||
CMD ["/bin/bash"]
|
||||
CMD ["/bin/bash"]
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
ARG BASE_IMAGE_TAG=latest
|
||||
FROM ere-base:${BASE_IMAGE_TAG}
|
||||
ARG BASE_IMAGE_TAG=ere-base:latest
|
||||
|
||||
FROM ${BASE_IMAGE_TAG}
|
||||
|
||||
# The ere-base image provides Rust, Cargo, and common tools.
|
||||
# We operate as root for SDK installation.
|
||||
@@ -20,13 +21,4 @@ ENV OPENVM_TOOLCHAIN_VERSION="nightly-2025-02-14"
|
||||
# Verify cargo-openvm is accessible with the correct toolchain
|
||||
RUN cargo "+${OPENVM_TOOLCHAIN_VERSION}" openvm --version
|
||||
|
||||
# Copy the entire ere project context
|
||||
# The WORKDIR is /app from the base image
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
|
||||
# Run tests
|
||||
RUN echo "Running tests for ere-openvm library..." && \
|
||||
cargo test --release -p ere-openvm --lib -- --color always
|
||||
|
||||
CMD ["/bin/bash"]
|
||||
CMD ["/bin/bash"]
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
ARG BASE_IMAGE_TAG=latest
|
||||
FROM ere-base:${BASE_IMAGE_TAG}
|
||||
ARG BASE_IMAGE_TAG=ere-base:latest
|
||||
|
||||
FROM ${BASE_IMAGE_TAG}
|
||||
|
||||
# The ere-base image provides Rust, Cargo, and common tools.
|
||||
# We operate as root for SDK installation.
|
||||
@@ -19,16 +20,10 @@ RUN /tmp/install_pico_sdk.sh && rm /tmp/install_pico_sdk.sh # Clean up the scrip
|
||||
# Define the Pico toolchain for convenience in subsequent commands if needed, though cargo pico should use it.
|
||||
ENV PICO_TOOLCHAIN_VERSION="nightly-2024-11-27"
|
||||
|
||||
# Set default toolchain
|
||||
RUN rustup default "$PICO_TOOLCHAIN_VERSION"
|
||||
|
||||
# Verify Pico installation
|
||||
RUN echo "Verifying Pico installation in Dockerfile (post-script)..." && cargo "+${PICO_TOOLCHAIN_VERSION}" pico --version
|
||||
RUN echo "Verifying Pico installation in Dockerfile (post-script)..." && cargo pico --version
|
||||
|
||||
# Copy the entire ere project context
|
||||
# The WORKDIR is /app from the base image
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
|
||||
# Run tests
|
||||
RUN echo "Running tests for ere-pico library..." && \
|
||||
cargo "+${PICO_TOOLCHAIN_VERSION}" test --release -p ere-pico --lib -- --color always
|
||||
|
||||
CMD ["/bin/bash"]
|
||||
CMD ["/bin/bash"]
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
[package]
|
||||
name = "risc0-cli"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
license.workspace = true
|
||||
|
||||
[dependencies]
|
||||
tempfile.workspace = true
|
||||
toml.workspace = true
|
||||
tracing.workspace = true
|
||||
clap.workspace = true
|
||||
anyhow.workspace = true
|
||||
hex.workspace = true
|
||||
zkvm-interface.workspace = true
|
||||
risc0-zkvm = { version = "^2.3.0", features = ["unstable"] }
|
||||
borsh = "1.5"
|
||||
bincode = "1.3"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
@@ -1,14 +1,6 @@
|
||||
ARG BASE_IMAGE_TAG=latest
|
||||
ARG BASE_IMAGE_TAG=ere-base:latest
|
||||
|
||||
FROM rust:1.85 AS builder
|
||||
|
||||
WORKDIR /risc0-cli
|
||||
|
||||
# Build `risc0-cli`
|
||||
COPY . .
|
||||
RUN cargo build --release -p risc0-cli
|
||||
|
||||
FROM ere-base:${BASE_IMAGE_TAG}
|
||||
FROM ${BASE_IMAGE_TAG}
|
||||
|
||||
# Copy and run the Risc0 SDK installer script
|
||||
COPY scripts/sdk_installers/install_risc0_sdk.sh /tmp/install_risc0_sdk.sh
|
||||
@@ -22,8 +14,4 @@ RUN echo "Verifying Risc0 installation in Dockerfile (post-script)..." && cargo
|
||||
# Get docker for `cargo risczero build`
|
||||
RUN curl -fsSL https://get.docker.com | sh
|
||||
|
||||
# Copy guest compiler binary
|
||||
COPY --from=builder /risc0-cli/target/release/risc0-cli /risc0-cli/risc0-cli
|
||||
|
||||
# Set entrypoint to `risc0-cli`
|
||||
ENTRYPOINT ["/risc0-cli/risc0-cli"]
|
||||
CMD ["/bin/bash"]
|
||||
|
||||
@@ -1,289 +0,0 @@
|
||||
use anyhow::Context;
|
||||
use clap::{Parser, Subcommand};
|
||||
use risc0_zkvm::{ExecutorEnv, ProverOpts, default_executor, default_prover};
|
||||
use std::{fs, path::PathBuf, process::Command};
|
||||
use toml::Value as TomlValue;
|
||||
use tracing::info;
|
||||
use zkvm_interface::{ProgramExecutionReport, ProgramProvingReport};
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(author, version)]
|
||||
struct Cli {
|
||||
#[command(subcommand)]
|
||||
command: Commands,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
enum Commands {
|
||||
/// Compile a guest program
|
||||
Compile {
|
||||
/// Path to the guest program crate directory.
|
||||
guest_folder: PathBuf,
|
||||
/// Output folder where compiled `guest.elf` and `image_id` will be placed.
|
||||
output_folder: PathBuf,
|
||||
},
|
||||
/// Execute a compiled program
|
||||
Execute {
|
||||
/// Path to the compiled ELF file
|
||||
elf_path: PathBuf,
|
||||
/// Path to the serialized input bytes file
|
||||
input_path: PathBuf,
|
||||
/// Path where the execution report will be written
|
||||
report_path: PathBuf,
|
||||
},
|
||||
/// Prove execution of a compiled program
|
||||
Prove {
|
||||
/// Path to the compiled ELF file
|
||||
elf_path: PathBuf,
|
||||
/// Path to the serialized input bytes file
|
||||
input_path: PathBuf,
|
||||
/// Path where the proof will be written
|
||||
proof_path: PathBuf,
|
||||
/// Path where the report will be written
|
||||
report_path: PathBuf,
|
||||
},
|
||||
}
|
||||
|
||||
pub fn main() -> anyhow::Result<()> {
|
||||
let args = Cli::parse();
|
||||
|
||||
match args.command {
|
||||
Commands::Compile {
|
||||
guest_folder,
|
||||
output_folder,
|
||||
} => compile(guest_folder, output_folder),
|
||||
Commands::Prove {
|
||||
elf_path,
|
||||
input_path,
|
||||
proof_path,
|
||||
report_path,
|
||||
} => prove(elf_path, input_path, proof_path, report_path),
|
||||
Commands::Execute {
|
||||
elf_path,
|
||||
input_path,
|
||||
report_path,
|
||||
} => execute(elf_path, input_path, report_path),
|
||||
}
|
||||
}
|
||||
|
||||
fn compile(guest_folder: PathBuf, output_folder: PathBuf) -> anyhow::Result<()> {
|
||||
let dir = guest_folder;
|
||||
|
||||
info!("Compiling Risc0 program at {}", dir.display());
|
||||
|
||||
if !dir.exists() || !dir.is_dir() {
|
||||
anyhow::bail!(
|
||||
"Program path does not exist or is not a directory: {}",
|
||||
dir.display()
|
||||
);
|
||||
}
|
||||
|
||||
let guest_manifest_path = dir.join("Cargo.toml");
|
||||
if !guest_manifest_path.exists() {
|
||||
anyhow::bail!(
|
||||
"Cargo.toml not found in program directory: {}. Expected at: {}",
|
||||
dir.display(),
|
||||
guest_manifest_path.display()
|
||||
);
|
||||
}
|
||||
|
||||
// ── read + parse Cargo.toml ───────────────────────────────────────────
|
||||
let manifest_content = fs::read_to_string(&guest_manifest_path)
|
||||
.with_context(|| format!("Failed to read file at {}", guest_manifest_path.display()))?;
|
||||
|
||||
let manifest_toml: TomlValue = manifest_content.parse::<TomlValue>().with_context(|| {
|
||||
format!(
|
||||
"Failed to parse guest Cargo.toml at {}",
|
||||
guest_manifest_path.display()
|
||||
)
|
||||
})?;
|
||||
|
||||
let program_name = manifest_toml
|
||||
.get("package")
|
||||
.and_then(|p| p.get("name"))
|
||||
.and_then(|n| n.as_str())
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"Could not find `[package].name` in guest Cargo.toml at {}",
|
||||
guest_manifest_path.display()
|
||||
)
|
||||
})?;
|
||||
|
||||
info!("Parsed program name: {program_name}");
|
||||
|
||||
// ── build into a temp dir ─────────────────────────────────────────────
|
||||
info!(
|
||||
"Running `cargo risczero build` → dir: {}",
|
||||
output_folder.display()
|
||||
);
|
||||
|
||||
let output = Command::new("cargo")
|
||||
.current_dir(&dir)
|
||||
.args(["risczero", "build"])
|
||||
.stderr(std::process::Stdio::inherit())
|
||||
.output()
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"Failed to execute `cargo risczer build` in {}",
|
||||
dir.display()
|
||||
)
|
||||
})?;
|
||||
|
||||
if !output.status.success() {
|
||||
anyhow::bail!(
|
||||
"Failed to execute `cargo risczero build` in {}",
|
||||
dir.display()
|
||||
)
|
||||
}
|
||||
|
||||
let (image_id, elf_path) = {
|
||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||
let line = stdout
|
||||
.lines()
|
||||
.find(|line| line.starts_with("ImageID: "))
|
||||
.unwrap();
|
||||
let (image_id, elf_path) = line
|
||||
.trim_start_matches("ImageID: ")
|
||||
.split_once(" - ")
|
||||
.unwrap();
|
||||
(image_id.to_string(), PathBuf::from(elf_path))
|
||||
};
|
||||
|
||||
if !elf_path.exists() {
|
||||
anyhow::bail!(
|
||||
"Compiled ELF not found at expected path: {}",
|
||||
elf_path.display()
|
||||
);
|
||||
}
|
||||
|
||||
let elf_bytes = fs::read(&elf_path)
|
||||
.with_context(|| format!("Failed to read file at {}", elf_path.display()))?;
|
||||
info!("Risc0 program compiled OK - {} bytes", elf_bytes.len());
|
||||
info!("Image ID - {image_id}");
|
||||
|
||||
fs::copy(&elf_path, output_folder.join("guest.elf")).with_context(|| {
|
||||
format!(
|
||||
"Failed to copy elf file from {} to {}",
|
||||
elf_path.display(),
|
||||
output_folder.join("guest.elf").display()
|
||||
)
|
||||
})?;
|
||||
fs::write(output_folder.join("image_id"), hex::decode(image_id)?).with_context(|| {
|
||||
format!(
|
||||
"Failed to write image id to {}",
|
||||
output_folder.join("image_id").display()
|
||||
)
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn execute(elf_path: PathBuf, input_path: PathBuf, report_path: PathBuf) -> anyhow::Result<()> {
|
||||
info!("Starting execution for ELF at {}", elf_path.display());
|
||||
|
||||
// Read the ELF file
|
||||
let elf = fs::read(&elf_path)
|
||||
.with_context(|| format!("Failed to read ELF file at {}", elf_path.display()))?;
|
||||
|
||||
// Read the serialized input bytes
|
||||
let input_bytes = fs::read(&input_path)
|
||||
.with_context(|| format!("Failed to read input bytes at {}", input_path.display()))?;
|
||||
|
||||
info!("ELF size: {} bytes", elf.len());
|
||||
info!("Input size: {} bytes", input_bytes.len());
|
||||
|
||||
// Create executor environment using write_slice to write the serialized input bytes directly
|
||||
let executor = default_executor();
|
||||
let env = ExecutorEnv::builder()
|
||||
.write_slice(&input_bytes)
|
||||
.build()
|
||||
.context("Failed to build executor environment")?;
|
||||
|
||||
info!("Starting execution...");
|
||||
let start = std::time::Instant::now();
|
||||
|
||||
// Execute the program
|
||||
let session_info = executor
|
||||
.execute(env, &elf)
|
||||
.context("Failed to execute program")?;
|
||||
|
||||
let execution_duration = start.elapsed();
|
||||
|
||||
info!("Execution completed in {:?}", execution_duration);
|
||||
info!("Total cycles: {}", session_info.cycles());
|
||||
|
||||
// Create execution report
|
||||
let report = ProgramExecutionReport {
|
||||
total_num_cycles: session_info.cycles() as u64,
|
||||
execution_duration,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
// Serialize and write the report
|
||||
let report_bytes =
|
||||
bincode::serialize(&report).context("Failed to serialize execution report")?;
|
||||
|
||||
fs::write(&report_path, report_bytes)
|
||||
.with_context(|| format!("Failed to write report to {}", report_path.display()))?;
|
||||
|
||||
info!("Execution report written to {}", report_path.display());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn prove(
|
||||
elf_path: PathBuf,
|
||||
input_path: PathBuf,
|
||||
proof_path: PathBuf,
|
||||
report_path: PathBuf,
|
||||
) -> anyhow::Result<()> {
|
||||
info!(
|
||||
"Starting proof generation for ELF at {}",
|
||||
elf_path.display()
|
||||
);
|
||||
|
||||
// Read the ELF file
|
||||
let elf = fs::read(&elf_path)
|
||||
.with_context(|| format!("Failed to read ELF file at {}", elf_path.display()))?;
|
||||
|
||||
// Read the serialized input bytes
|
||||
let input_bytes = fs::read(&input_path)
|
||||
.with_context(|| format!("Failed to read input bytes at {}", input_path.display()))?;
|
||||
|
||||
info!("ELF size: {} bytes", elf.len());
|
||||
info!("Input size: {} bytes", input_bytes.len());
|
||||
|
||||
// Create prover environment using write_slice to write the serialized input bytes directly
|
||||
let prover = default_prover();
|
||||
let env = ExecutorEnv::builder()
|
||||
.write_slice(&input_bytes)
|
||||
.build()
|
||||
.context("Failed to build executor environment")?;
|
||||
|
||||
info!("Starting proof generation...");
|
||||
|
||||
let now = std::time::Instant::now();
|
||||
|
||||
// Generate proof
|
||||
let prove_info = prover
|
||||
.prove_with_opts(env, &elf, &ProverOpts::succinct())
|
||||
.context("Failed to generate proof")?;
|
||||
|
||||
let proving_time = now.elapsed();
|
||||
|
||||
info!("Proof generation completed in {:?}", proving_time);
|
||||
|
||||
// Serialize and write the proof
|
||||
let proof_bytes = borsh::to_vec(&prove_info.receipt).context("Failed to serialize proof")?;
|
||||
fs::write(&proof_path, proof_bytes)
|
||||
.with_context(|| format!("Failed to write proof to {}", proof_path.display()))?;
|
||||
|
||||
let report_bytes = bincode::serialize(&ProgramProvingReport::new(proving_time))
|
||||
.context("Failed to serialize report")?;
|
||||
fs::write(&report_path, report_bytes)
|
||||
.with_context(|| format!("Failed to write report to {}", report_path.display()))?;
|
||||
|
||||
info!("Proof written to {}", proof_path.display());
|
||||
info!("Report written to {}", report_path.display());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
[package]
|
||||
name = "sp1-guest-compiler"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
license.workspace = true
|
||||
|
||||
[dependencies]
|
||||
tempfile.workspace = true
|
||||
toml.workspace = true
|
||||
tracing.workspace = true
|
||||
clap.workspace = true
|
||||
anyhow.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
@@ -1,23 +1,9 @@
|
||||
ARG BASE_IMAGE_TAG=latest
|
||||
ARG BASE_IMAGE_TAG=ere-base:latest
|
||||
|
||||
# Build guest-compiler binary
|
||||
FROM rust:1.85 AS builder
|
||||
RUN apt-get update && apt-get install -y build-essential libclang-dev
|
||||
WORKDIR /guest-compiler
|
||||
COPY . .
|
||||
RUN cargo build --release -p sp1-guest-compiler
|
||||
|
||||
# Build zkVM builder image
|
||||
FROM ere-base:${BASE_IMAGE_TAG}
|
||||
FROM ${BASE_IMAGE_TAG}
|
||||
|
||||
ARG USERNAME=ere_user
|
||||
|
||||
# Ensure Cargo/Rustup environment variables are set from the base image for SDK script
|
||||
# TODO: These should be inherited from ere-base.
|
||||
ENV RUSTUP_HOME=${RUSTUP_HOME:-/usr/local/rustup} \
|
||||
CARGO_HOME=${CARGO_HOME:-/usr/local/cargo} \
|
||||
PATH=${PATH:-/usr/local/cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin}
|
||||
|
||||
# Copy the SP1 SDK installer script
|
||||
COPY scripts/sdk_installers/install_sp1_sdk.sh /tmp/install_sp1_sdk.sh
|
||||
RUN chmod +x /tmp/install_sp1_sdk.sh
|
||||
@@ -41,11 +27,7 @@ ENV PATH="${SP1UP_HOME}/bin:${SP1_HOME}/bin:$PATH"
|
||||
# Verify SP1 installation (optional here, as script does it, but good for sanity)
|
||||
RUN cargo prove --version
|
||||
|
||||
# Copy guest compiler binary
|
||||
COPY --from=builder /guest-compiler/target/release/sp1-guest-compiler /guest-compiler/guest-compiler
|
||||
WORKDIR /guest-compiler
|
||||
|
||||
CMD ["/bin/bash"]
|
||||
CMD ["/bin/bash"]
|
||||
|
||||
# TODO: Maybe we use root to install it in ere_user and then switch back to ere_user for security
|
||||
# USER ${USERNAME} # Switch to non-root user again
|
||||
# USER ${USERNAME} # Switch to non-root user again
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
use std::{fs, path::PathBuf, process::Command};
|
||||
|
||||
use anyhow::Context;
|
||||
use clap::Parser;
|
||||
use toml::Value as TomlValue;
|
||||
use tracing::info;
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(author, version)]
|
||||
struct Cli {
|
||||
/// Path to the guest program crate directory.
|
||||
guest_folder: PathBuf,
|
||||
|
||||
/// Compiled ELF output folder where guest.elf will be placed.
|
||||
elf_output_folder: PathBuf,
|
||||
}
|
||||
|
||||
pub fn main() -> anyhow::Result<()> {
|
||||
let args = Cli::parse();
|
||||
|
||||
let dir = args.guest_folder;
|
||||
|
||||
info!("Compiling SP1 program at {}", dir.display());
|
||||
|
||||
if !dir.exists() || !dir.is_dir() {
|
||||
anyhow::bail!(
|
||||
"Program path does not exist or is not a directory: {}",
|
||||
dir.display()
|
||||
);
|
||||
}
|
||||
|
||||
let guest_manifest_path = dir.join("Cargo.toml");
|
||||
if !guest_manifest_path.exists() {
|
||||
anyhow::bail!(
|
||||
"Cargo.toml not found in program directory: {}. Expected at: {}",
|
||||
dir.display(),
|
||||
guest_manifest_path.display()
|
||||
);
|
||||
}
|
||||
|
||||
// ── read + parse Cargo.toml ───────────────────────────────────────────
|
||||
let manifest_content = fs::read_to_string(&guest_manifest_path)
|
||||
.with_context(|| format!("Failed to read file at {}", guest_manifest_path.display()))?;
|
||||
|
||||
let manifest_toml: TomlValue = manifest_content.parse::<TomlValue>().with_context(|| {
|
||||
format!(
|
||||
"Failed to parse guest Cargo.toml at {}",
|
||||
guest_manifest_path.display()
|
||||
)
|
||||
})?;
|
||||
|
||||
let program_name = manifest_toml
|
||||
.get("package")
|
||||
.and_then(|p| p.get("name"))
|
||||
.and_then(|n| n.as_str())
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"Could not find `[package].name` in guest Cargo.toml at {}",
|
||||
guest_manifest_path.display()
|
||||
)
|
||||
})?;
|
||||
|
||||
info!("Parsed program name: {program_name}");
|
||||
|
||||
// ── build into a temp dir ─────────────────────────────────────────────
|
||||
info!(
|
||||
"Running `cargo prove build` → dir: {}",
|
||||
args.elf_output_folder.display()
|
||||
);
|
||||
|
||||
let status = Command::new("cargo")
|
||||
.current_dir(&dir)
|
||||
.args([
|
||||
"prove",
|
||||
"build",
|
||||
"--output-directory",
|
||||
args.elf_output_folder.to_str().unwrap(),
|
||||
"--elf-name",
|
||||
"guest.elf",
|
||||
])
|
||||
.stdout(std::process::Stdio::inherit())
|
||||
.stderr(std::process::Stdio::inherit())
|
||||
.status()
|
||||
.with_context(|| format!("Failed to execute `cargo prove build` in {}", dir.display()))?;
|
||||
|
||||
if !status.success() {
|
||||
anyhow::bail!("Failed to execute `cargo prove build` in {}", dir.display())
|
||||
}
|
||||
|
||||
let elf_path = args.elf_output_folder.join("guest.elf");
|
||||
if !elf_path.exists() {
|
||||
anyhow::bail!(
|
||||
"Compiled ELF not found at expected path: {}",
|
||||
elf_path.display()
|
||||
);
|
||||
}
|
||||
|
||||
let elf_bytes = fs::read(&elf_path)
|
||||
.with_context(|| format!("Failed to read file at {}", elf_path.display()))?;
|
||||
info!("SP1 program compiled OK - {} bytes", elf_bytes.len());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -1,18 +1,18 @@
|
||||
ARG BASE_IMAGE_TAG=latest
|
||||
FROM ere-base:${BASE_IMAGE_TAG}
|
||||
ARG BASE_IMAGE_TAG=ere-base:latest
|
||||
|
||||
FROM ${BASE_IMAGE_TAG}
|
||||
|
||||
# The ere-base image provides Rust, Cargo, and common tools.
|
||||
# ZisK requires Ubuntu 22.04 or higher (ere-base uses 22.04 by default).
|
||||
# ZisK requires Ubuntu 22.04 or higher (ere-base uses 24.04 by default).
|
||||
# We operate as root for SDK and dependency installation.
|
||||
|
||||
# Install ZisK system dependencies (for Ubuntu)
|
||||
# Taken from https://0xpolygonhermez.github.io/zisk/getting_started/installation.html
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
xz-utils \
|
||||
jq \
|
||||
# build-essential is in ere-base
|
||||
# jq is in ere-base
|
||||
# curl is in ere-base
|
||||
# git is in ere-base
|
||||
# build-essential is in ere-base
|
||||
qemu-system \
|
||||
libomp-dev \
|
||||
libgmp-dev \
|
||||
@@ -28,7 +28,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
openmpi-bin \
|
||||
openmpi-common \
|
||||
libclang-dev \
|
||||
clang
|
||||
clang && \
|
||||
apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN wget https://developer.download.nvidia.com/compute/cuda/repos/$(. /etc/os-release && echo "${ID}${VERSION_ID}" | tr -d '.')/$(uname -i)/cuda-keyring_1.1-1_all.deb && \
|
||||
dpkg -i cuda-keyring_1.1-1_all.deb && \
|
||||
@@ -37,14 +38,21 @@ RUN wget https://developer.download.nvidia.com/compute/cuda/repos/$(. /etc/os-re
|
||||
apt install -y cuda-toolkit && \
|
||||
apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# If current environment is in CI or not.
|
||||
ARG CI
|
||||
|
||||
# Copy the ZisK SDK installer script from the workspace context
|
||||
COPY scripts/sdk_installers/install_zisk_sdk.sh /tmp/install_zisk_sdk.sh
|
||||
RUN chmod +x /tmp/install_zisk_sdk.sh
|
||||
|
||||
# Run the ZisK SDK installation script using ziskup.
|
||||
# This script installs the 'zisk' Rust toolchain and cargo-zisk.
|
||||
# TODO: Download the proving key if the CI runner has enough disk space.
|
||||
RUN SETUP_KEY=verify /tmp/install_zisk_sdk.sh && rm /tmp/install_zisk_sdk.sh # Clean up the script
|
||||
# This script installs the 'zisk' Rust toolchain and `cargo-zisk`
|
||||
#
|
||||
# If argument `CI` is set, we only install verifying key, this is used by github
|
||||
# CI runner which only has small disk space (proving key requires ~35 GB).
|
||||
RUN if [ -n "$CI" ]; then export SETUP_KEY=verify; fi && \
|
||||
/tmp/install_zisk_sdk.sh && \
|
||||
rm /tmp/install_zisk_sdk.sh # Clean up the script
|
||||
|
||||
# The 'zisk' Rust toolchain is now installed.
|
||||
# cargo-zisk is installed in /root/.zisk/bin.
|
||||
@@ -56,16 +64,4 @@ ENV PATH="${PATH}:${ZISK_BIN_DIR}"
|
||||
# Verify cargo-zisk is accessible
|
||||
RUN echo "Verifying Zisk installation in Dockerfile ..." && cargo-zisk --version
|
||||
|
||||
# Copy the entire ere project context
|
||||
# The WORKDIR is /app from the base image
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
|
||||
# Run only compile and execution test, because proving requires ~31 GiB disk
|
||||
# space for the provingKey.
|
||||
# TODO: Run all tests if the CI runner has enough disk space to install the proving key.
|
||||
RUN echo "Running tests for ere-zisk library..." && \
|
||||
rm -rf ~/.zisk/provingKey && \
|
||||
cargo test --release -p ere-zisk --lib -- --color always compile::tests execute_tests
|
||||
|
||||
CMD ["/bin/bash"]
|
||||
CMD ["/bin/bash"]
|
||||
|
||||
Reference in New Issue
Block a user