Skip to content

Commit

Permalink
Feature: Stone Prover SDK (#1)
Browse files Browse the repository at this point in the history
* Feature: Stone Prover SDK

Imported the code from the Madara Prover API.
  • Loading branch information
odesenfans authored Feb 14, 2024
1 parent d0ee1bc commit 41ed9bf
Show file tree
Hide file tree
Showing 16 changed files with 1,378 additions and 2 deletions.
81 changes: 81 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
name: Tests

on:
push:
branches:
- "main"
pull_request:
branches:
- "*"

env:
CARGO_TERM_COLOR: always

jobs:
build:

runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v3
with:
submodules: recursive

- name: Install Rust
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: 1.73
override: true
components: rustfmt, clippy

- name: Set up cargo cache
uses: actions/cache@v3
continue-on-error: false
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: ${{ runner.os }}-cargo-

- name: Log in to Github container registry
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin

- name: Set cache image environment variables
run: |
# Uppercase characters are not allowed in Docker tags
cache_image=$(echo ghcr.io/${GITHUB_REPOSITORY}/build-cache | tr '[:upper:]' '[:lower:]')
echo "STONE_PROVER_DOCKER_CACHE=$(echo ${cache_image})" >> $GITHUB_ENV
- name: Download Docker cache image (if available)
run: docker pull ${STONE_PROVER_DOCKER_CACHE} || true

- name: Build
run: cargo build --verbose

- name: Lint with Clippy
run: cargo clippy -- -D warnings

- name: Run tests
run: cargo test --verbose

- name: Set release artifacts
uses: softprops/action-gh-release@v1
if: startsWith(github.ref, 'refs/tags/')
with:
files: |
target/debug/cpu_air_prover
target/debug/cpu_air_verifier
- name: Push the image to the cache
# It's not possible to push packages from fork PRs.
if: github.event.pull_request.head.repo.full_name == github.repository
run: |
docker tag stone-prover-build:latest ${STONE_PROVER_DOCKER_CACHE}
docker push ${STONE_PROVER_DOCKER_CACHE}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@ Cargo.lock

# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb

# IDE files
.idea/
6 changes: 6 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[submodule "dependencies/stone-prover"]
path = dependencies/stone-prover
url = https://github.com/starkware-libs/stone-prover.git
[submodule "dependencies/cairo-programs"]
path = dependencies/cairo-programs
url = https://github.com/Moonsong-Labs/cairo-programs.git
20 changes: 20 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[package]
name = "stone-prover-sdk"
version = "0.1.0"
edition = "2021"
description = "Rust SDK for the Starkware Stone prover and verifier."
build = "build.rs"

[dependencies]
bincode = "2.0.0-rc.3"
cairo-vm = { git = "https://github.com/Moonsong-Labs/cairo-vm", rev = "b2f69d230416129a84ad8237ccc13d088992f74b", features=["extensive_hints"] }
serde = { version = "1.0.192", features = ["derive"] }
serde_json = "1.0.108"
stark_evm_adapter = "0.1.5"
tempfile = "3.8.1"
thiserror = "1.0.50"
tokio = { version = "1.34.0", features = ["macros", "process", "rt-multi-thread"] }


[dev-dependencies]
rstest = "0.18.2"
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
# stone-prover-sdk
Rust SDK for the Stone prover and verifier.
# Stone Prover SDK

Rust SDK for the Starkware Stone prover and verifier.
131 changes: 131 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
/// Builds the Stone Prover C++ submodule to make it callable from the wrapper.
use std::path::{Path, PathBuf};

#[derive(Debug)]
enum CommandError {
/// The command failed with a non-zero return code.
CommandFailed(std::process::Output),
/// The command could not be launched.
IoError(std::io::Error),
}

impl From<std::io::Error> for CommandError {
fn from(value: std::io::Error) -> Self {
Self::IoError(value)
}
}

/// Run any shell command line and retrieve its output.
fn run_command(command: &str) -> Result<std::process::Output, CommandError> {
let output = std::process::Command::new("sh")
.arg("-c")
.arg(command)
.output()?;

if !output.status.success() {
return Err(CommandError::CommandFailed(output));
}
Ok(output)
}

/// Copy a file from a running Docker container.
fn copy_file_from_container(
container_name: &str,
container_file: &Path,
target: &Path,
) -> Result<(), CommandError> {
let docker_copy_command = format!(
"docker cp -L {container_name}:{} {}",
container_file.to_string_lossy(),
target.to_string_lossy()
);
let _ = run_command(&docker_copy_command);
Ok(())
}

/// Copy the prover and verifier binary files from the prover build container.
fn copy_prover_files_from_container(
container_name: &str,
output_dir: &Path,
) -> Result<(), CommandError> {
copy_file_from_container(container_name, Path::new("/bin/cpu_air_prover"), output_dir)?;
copy_file_from_container(
container_name,
Path::new("/bin/cpu_air_verifier"),
output_dir,
)?;

Ok(())
}

fn make_docker_build_command(repo_dir: &Path, image_name: &str) -> String {
let mut docker_build_command = format!(
"docker build -t {image_name} {}",
repo_dir.to_string_lossy()
);

// Check if the platform is Mac
#[cfg(target_os = "macos")]
{
// Add build args
docker_build_command.push_str(" --build-arg CMAKE_ARGS=-DNO_AVX=1");
}

// Check if a cache image exists. Used by the CI/CD pipeline.
if let Ok(cache_image) = std::env::var("STONE_PROVER_DOCKER_CACHE") {
docker_build_command.push_str(&format!(" --cache-from {cache_image}"));
}

docker_build_command
}

/// Build the Stone Prover and copy binaries to `output_dir`.
///
/// The prover repository contains a Dockerfile to build the prover. This function:
/// 1. Builds the Dockerfile
/// 2. Starts a container based on the generated image
/// 3. Extracts the binaries from the container
/// 4. Stops the container.
fn build_stone_prover(repo_dir: &Path, output_dir: &Path) {
// Build the Stone Prover build Docker image
let image_name = "stone-prover-build:latest";
let docker_build_command = make_docker_build_command(repo_dir, image_name);
run_command(&docker_build_command).expect("Failed to build Stone Prover using Dockerfile");

// Run a container based on the Docker image
let docker_create_command = format!("docker create {image_name}");
let docker_create_output = run_command(&docker_create_command)
.expect("Failed to start container to copy prover files");
let container_name = String::from_utf8_lossy(&docker_create_output.stdout)
.trim()
.to_owned();
println!("Started container {container_name}");

// Copy the files
let copy_result = copy_prover_files_from_container(&container_name, output_dir);

// Stop the container
let docker_delete_command = format!("docker rm {container_name}");
run_command(&docker_delete_command).expect("Failed to stop and delete prover build container");

// Handle a potential error during copy
if let Err(e) = copy_result {
panic!(
"Failed to copy files from the prover build container: {:?}",
e
);
}
}

fn main() {
let out_dir = PathBuf::from(std::env::var("OUT_DIR").unwrap());
// Copy the prover and verifier to the root of the target directory
// to make them easy to find for all the crates in the workspace.
let target_dir = out_dir.join("../../..").canonicalize().unwrap();

let stone_prover_repo_dir = Path::new("dependencies/stone-prover");
build_stone_prover(stone_prover_repo_dir, target_dir.as_path());

// Rerun if the submodule is updated
println!("cargo:rerun-if-changed=.git/modules/dependencies/stone-prover/HEAD");
}
1 change: 1 addition & 0 deletions dependencies/cairo-programs
Submodule cairo-programs added at 2e5b91
1 change: 1 addition & 0 deletions dependencies/stone-prover
Submodule stone-prover added at 00b274
Loading

0 comments on commit 41ed9bf

Please sign in to comment.