Skip to content

Commit

Permalink
Internal: build Stone separately from the SDK (#4)
Browse files Browse the repository at this point in the history
Problem: the build time of the SDK reaches ~20 minutes, which is not
acceptable to users. This is due to the compilation of Stone in the
`build.rs` file.

Solution: we now build and install Stone from a Shell script that is
isolated from the Rust compilation process. Developers must now run this
script before attempting to run tests, but this accelerates the build
process significantly.
  • Loading branch information
odesenfans authored Feb 16, 2024
1 parent d4111ae commit d5926ea
Show file tree
Hide file tree
Showing 9 changed files with 160 additions and 202 deletions.
48 changes: 26 additions & 22 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
components: rustfmt, clippy

- name: Set up cargo cache
uses: actions/cache@v3
uses: actions/cache@v4
continue-on-error: false
with:
path: |
Expand All @@ -45,39 +45,43 @@ jobs:
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
- name: Get Stone submodule version
id: get-stone-version
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
echo "stone_version=$(cat .git/modules/dependencies/stone-prover/HEAD)" >> $GITHUB_OUTPUT
- name: Cache Stone prover and verifier
id: cache-stone
uses: actions/cache@v4
with:
path: dependencies/stone
key: stone-${{ runner.os }}-${{ steps.get-stone-version.outputs.stone_version }}

- name: Download Docker cache image (if available)
run: docker pull ${STONE_PROVER_DOCKER_CACHE} || true
- name: Build Stone
if: steps.cache-stone.outputs.cache-hit != 'true'
run: |
bash -x scripts/install-stone.sh --install-dir ./dependencies/stone
- name: Set Stone in PATH
run: |
echo "$(pwd)/dependencies/stone" >> $GITHUB_PATH
- name: Build
run: cargo build --verbose
run: |
cargo build --verbose
- name: Lint with Clippy
run: cargo clippy -- -D warnings
run: |
cargo clippy -- -D warnings
- name: Run tests
run: cargo test --verbose
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}
dependencies/stone/cpu_air_prover
dependencies/stone/cpu_air_verifier
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ 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"
Expand Down
47 changes: 47 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,50 @@
# Stone Prover SDK

Rust SDK for the Starkware Stone prover and verifier.

## Install

To use this SDK, you will need the Stone prover and verifier binaries.
You can either follow the instructions on the [Stone repository](https://github.com/starkware-libs/stone-prover),
download them from the [latest SDK release](https://github.com/Moonsong-Labs/stone-prover-sdk/releases/latest)
or run the following commands:

```shell
git clone --recurse-submodules https://github.com/Moonsong-Labs/stone-prover-sdk.git
cd stone-prover-sdk
bash scripts/install-stone.sh
```

This will install the prover and verifier in `${HOME}/.stone` and add this directory to your `PATH`.

## Features

### Prove and verify Cairo programs

The `prover` and `verifier` modules contain thin abstractions on top of the prover and verifier.
They allow the user to prove and verify the execution of any Cairo program from Rust code.

### Execute Cairo programs

The `cairo_vm` module provides utility functions over the [cairo-vm](https://github.com/Moonsong-Labs/cairo-vm)
crate to execute Cairo programs using the Rust Cairo VM.

## Contribute

### Set up the development environment

First, clone the repository and install Stone:

```shell
git clone --recurse-submodules https://github.com/Moonsong-Labs/stone-prover-sdk.git
cd stone-prover-sdk
bash scripts/install-stone.sh
```

This step takes several minutes. The script adds the install directory (`$HOME/.stone` by default) to your `PATH`
for supported shells. Make sure that this is the case:

```shell
which cpu_air_prover
# Should print <install-dir>/cpu_air_prover
```
131 changes: 0 additions & 131 deletions build.rs

This file was deleted.

32 changes: 32 additions & 0 deletions scripts/build-stone.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/usr/bin/env bash

set -eo pipefail

SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
OUTPUT_DIR="$(pwd)"

while true; do
case "$1" in
-o | --output-dir ) OUTPUT_DIR="$2"; shift 2 ;;
* ) break ;;
esac
done

mkdir -p "${OUTPUT_DIR}"

STONE_DIR="${SCRIPT_DIR}/../dependencies/stone-prover"

STONE_GIT_TAG=$(cat .git/modules/dependencies/stone-prover/HEAD)
IMAGE_NAME="stone-prover-build:${STONE_GIT_TAG}"
ARCH_NAME=$(uname -m)

BUILD_FLAGS=""
if [ "${ARCH_NAME}" == "arm64" ]; then BUILD_FLAGS="--build-arg CMAKE_ARGS=-DNO_AVX=1"; fi

docker build -t "${IMAGE_NAME}" ${BUILD_FLAGS} "${STONE_DIR}"

CONTAINER=$(docker create "${IMAGE_NAME}")
docker cp -L "${CONTAINER}:/bin/cpu_air_prover" "${OUTPUT_DIR}"
docker cp -L "${CONTAINER}:/bin/cpu_air_verifier" "${OUTPUT_DIR}"

docker rm "${CONTAINER}"
43 changes: 43 additions & 0 deletions scripts/install-stone.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/usr/bin/env bash

set -eo pipefail

SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )

INSTALL_DIR="${HOME}/.stone"

while true; do
case "$1" in
-i | --install-dir ) INSTALL_DIR="$2"; shift 2 ;;
* ) break ;;
esac
done

echo "Installing Stone in ${INSTALL_DIR}..."
mkdir -p "${INSTALL_DIR}"
bash "${SCRIPT_DIR}/build-stone.sh" --output-dir "${INSTALL_DIR}"

# Add the tool to the PATH

echo "Configuring PATH..."
if [[ ":$PATH:" != *":${INSTALL_DIR}:"* ]]; then
PROFILE_FILE=""
# ZSH_NAME is set on zsh
if [ -v ZSH_NAME ]; then
PROFILE_FILE="${HOME}/.zsh"
elif [ -v BASH ]; then
PROFILE_FILE="${HOME}/.bashrc"
else
echo "Unsupported shell, you will need to add the export PATH statement in the right configuration file manually."
fi

if [ -n "${PROFILE_FILE}" ]; then
echo -e "\n# Stone prover and verifier\nexport PATH=\"${INSTALL_DIR}:\$PATH\"" >> "${PROFILE_FILE}"
fi
fi

# Notify the user to update the PATH immediately
echo "Done!"
echo "Stone was added to ${PROFILE_FILE} and will be available the next time you open a shell."
echo "To add Stone to your PATH immediately, run the following command:"
echo "export PATH=\"${INSTALL_DIR}:\$PATH\""
19 changes: 5 additions & 14 deletions src/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,18 +232,15 @@ mod test {
use tempfile::NamedTempFile;

use crate::test_utils::{
parsed_prover_test_case, prover_cli_test_case, prover_in_path, read_proof_file,
ParsedProverTestCase, ProverCliTestCase,
parsed_prover_test_case, prover_cli_test_case, read_proof_file, ParsedProverTestCase,
ProverCliTestCase,
};

use super::*;

/// Check that the Stone Prover command-line wrapper works.
#[rstest]
fn test_run_prover_from_command_line(
prover_cli_test_case: ProverCliTestCase,
#[from(prover_in_path)] _path: (),
) {
fn test_run_prover_from_command_line(prover_cli_test_case: ProverCliTestCase) {
let output_file = NamedTempFile::new().expect("Creating output file failed");
run_prover_from_command_line(
&prover_cli_test_case.public_input_file,
Expand All @@ -259,10 +256,7 @@ mod test {
}

#[rstest]
fn test_run_prover(
parsed_prover_test_case: ParsedProverTestCase,
#[from(prover_in_path)] _path: (),
) {
fn test_run_prover(parsed_prover_test_case: ParsedProverTestCase) {
let proof = run_prover(
&parsed_prover_test_case.public_input,
&parsed_prover_test_case.private_input,
Expand All @@ -278,10 +272,7 @@ mod test {

#[rstest]
#[tokio::test]
async fn test_run_prover_async(
parsed_prover_test_case: ParsedProverTestCase,
#[from(prover_in_path)] _path: (),
) {
async fn test_run_prover_async(parsed_prover_test_case: ParsedProverTestCase) {
let proof = run_prover_async(
&parsed_prover_test_case.public_input,
&parsed_prover_test_case.private_input,
Expand Down
Loading

0 comments on commit d5926ea

Please sign in to comment.