Skip to content

Commit

Permalink
Introducing the Stone Prover CLI (#1)
Browse files Browse the repository at this point in the history
This new CLI tool enables users to run, prove and verify Cairo programs
from a single tool with a simplified interface.

Features:
* Run, prove and verify any Cairo program
* Run programs directly or with the Starknet bootloader for
  compatibility with the Starknet L1 verifier
* Automatic generation of the prover configuration and parameters.
  • Loading branch information
odesenfans authored Feb 21, 2024
1 parent dd3bda4 commit 0d014d4
Show file tree
Hide file tree
Showing 18 changed files with 898 additions and 2 deletions.
93 changes: 93 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
name: CI/CD

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

env:
CARGO_TERM_COLOR: always
STONE_SDK_VERSION: v0.3.0
STONE_INSTALL_DIR: ./dependencies/stone

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.74
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: Set Stone SDK version in context
id: set-env-sdk-version
run: |
echo "STONE_SDK_VERSION=${STONE_SDK_VERSION}" >> $GITHUB_ENV
echo "STONE_INSTALL_DIR=${STONE_INSTALL_DIR}" >> $GITHUB_ENV
- name: Cache Stone prover and verifier
id: cache-stone
uses: actions/cache@v4
with:
path: ${{ env.STONE_INSTALL_DIR }}
key: stone-${{ runner.os }}-${{ env.STONE_SDK_VERSION }}

- name: Download Stone
if: steps.cache-stone.outputs.cache-hit != 'true'
run: |
mkdir -p "${STONE_INSTALL_DIR}"
wget https://github.com/Moonsong-Labs/stone-prover-sdk/releases/download/${STONE_SDK_VERSION}/cpu_air_prover -O "${STONE_INSTALL_DIR}/cpu_air_prover"
wget https://github.com/Moonsong-Labs/stone-prover-sdk/releases/download/${STONE_SDK_VERSION}/cpu_air_verifier -O "${STONE_INSTALL_DIR}/cpu_air_verifier"
- name: Set Stone in PATH
run: |
INSTALL_DIR=$(readlink -f ${STONE_INSTALL_DIR})
echo "${INSTALL_DIR}" >> $GITHUB_PATH
chmod +x ${INSTALL_DIR}/cpu_air_prover
chmod +x ${INSTALL_DIR}/cpu_air_verifier
- name: Lint with Clippy
run: |
cargo clippy -- -D warnings
- name: Build
run: |
cargo build --release --verbose
- name: Run tests
run: |
cargo test --verbose
- name: Upload release artifacts
uses: softprops/action-gh-release@v1
if: startsWith(github.ref, 'refs/tags/')
with:
files: |
target/release/stone-prover-cli
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,13 @@ Cargo.lock

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

# Added by cargo
/target

# IDE files
.idea/

# Stone prover and verifier
dependencies/cpu_air_prover
dependencies/cpu_air_verifier
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "dependencies/cairo-programs"]
path = dependencies/cairo-programs
url = https://github.com/Moonsong-Labs/cairo-programs.git
18 changes: 18 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[package]
name = "stone-prover-cli"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
cairo-vm = { git = "https://github.com/Moonsong-Labs/cairo-vm", rev = "b2f69d230416129a84ad8237ccc13d088992f74b", features = ["extensive_hints"] }
clap = { version = "4.5.0", features = ["derive"] }
serde = { version = "1.0.196", features = ["derive"] }
serde_json = { version = "1.0.113" }
stone-prover-sdk = { git = "https://github.com/Moonsong-Labs/stone-prover-sdk", tag="v0.3.0" }
thiserror = { version = "1.0.57" }

[dev-dependencies]
rstest = "0.18.2"
tempfile = "3.10.0"
24 changes: 24 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
.PHONY: deps all-tests clean distclean unit-tests integration-tests

PROVER_BIN=dependencies/cpu_air_prover
VERIFIER_BIN=dependencies/cpu_air_verifier

$(PROVER_BIN):
wget -O dependencies/cpu_air_prover https://github.com/Moonsong-Labs/stone-prover-sdk/releases/download/v0.1.0-rc1/cpu_air_prover

$(VERIFIER_BIN):
wget -O dependencies/cpu_air_verifier https://github.com/Moonsong-Labs/stone-prover-sdk/releases/download/v0.1.0-rc1/cpu_air_verifier

all-tests: deps
cargo test

itests: deps
cargo test --release --test '*'

deps: $(PROVER_BIN) $(VERIFIER_BIN)
clean:
cargo clean

distclean: clean
rm -rf dependencies/cpu_air_prover
rm -rf dependencies/cpu_air_verifier
32 changes: 30 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,30 @@
# stone-prover-cli
A CLI to run and prove Cairo programs.
# Stone Prover CLI

A CLI to run, prove and verify Cairo programs with a simple interface.

Features:

* Run, prove and verify any Cairo program
* Run programs directly or with the Starknet bootloader for
compatibility with the Starknet L1 verifier
* Automatic generation of the prover configuration and parameters.

## Usage

### Run and prove a single program

```shell
stone-prover-cli prove program.json
```

### Run and prove one or more programs/PIEs with the Starknet bootloader

```shell
stone-prover-cli prove --with-bootloader program1.json program2.json pie1.zip
```

### Verify a proof

```shell
stone-prover-cli verify proof.json
```
1 change: 1 addition & 0 deletions dependencies/cairo-programs
Submodule cairo-programs added at 2e5b91
43 changes: 43 additions & 0 deletions scripts/install-stone-cli.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}"
wget https://github.com/Moonsong-Labs/stone-prover-sdk/releases/download/v0.2.0/cpu_air_prover -O "${INSTALL_DIR}/cpu_air_prover"
wget https://github.com/Moonsong-Labs/stone-prover-sdk/releases/download/v0.2.0/cpu_air_verifier -O "${INSTALL_DIR}/cpu_air_verifier"

# 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\""
130 changes: 130 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
use clap::error::ErrorKind;
use clap::{Args, CommandFactory, Parser, Subcommand};
use std::borrow::Cow;
use std::path::{Path, PathBuf};
use stone_prover_sdk::models::Layout;

#[derive(Parser, Debug)]
#[command(name = "stone")]
#[command(bin_name = "stone")]
pub enum Cli {
Prove(ProveArgs),
Verify(VerifyArgs),
}

#[derive(Args, Debug)]
#[command(args_conflicts_with_subcommands = true)]
#[command(flatten_help = true)]
pub struct ProveArgs {
#[clap(long = "with-bootloader", default_value_t = false)]
pub with_bootloader: bool,

#[clap(long = "program-input")]
pub program_input: Option<PathBuf>,

#[clap(long = "layout")]
pub layout: Option<Layout>,

#[clap(flatten)]
pub config: ConfigArgs,

#[arg(required=true, num_args=1..)]
pub programs: Vec<PathBuf>,
}

impl ProveArgs {
pub fn command(mut self) -> ProveCommand {
let mut cmd = Cli::command();
if self.with_bootloader {
if self.program_input.is_some() {
cmd.error(
ErrorKind::ArgumentConflict,
"Cannot load program input in bootloader mode",
)
.exit();
}
} else if self.programs.len() > 1 {
cmd.error(
ErrorKind::ArgumentConflict,
"Cannot prove multiple programs without bootloader",
)
.exit();
}

if self.with_bootloader {
let args = ProveWithBootloaderArgs {
programs: self.programs,
config: self.config,
};
return ProveCommand::WithBootloader(args);
}
let args = ProveBareArgs {
program: self.programs.remove(0),
program_input: self.program_input,
layout: self.layout,
config: self.config,
};
ProveCommand::Bare(args)
}
}

#[derive(Subcommand, Debug)]
pub enum ProveCommand {
Bare(ProveBareArgs),
WithBootloader(ProveWithBootloaderArgs),
}

impl ProveCommand {
pub fn config(&self) -> &ConfigArgs {
match self {
ProveCommand::Bare(args) => &args.config,
ProveCommand::WithBootloader(args) => &args.config,
}
}
}

#[derive(Args, Debug)]
pub struct ProveBareArgs {
pub program: PathBuf,

#[clap(long = "program-input")]
pub program_input: Option<PathBuf>,

#[clap(long = "layout")]
pub layout: Option<Layout>,

#[clap(flatten)]
pub config: ConfigArgs,
}

#[derive(Args, Debug)]
pub struct ProveWithBootloaderArgs {
pub programs: Vec<PathBuf>,

#[clap(flatten)]
pub config: ConfigArgs,
}

#[derive(Args, Clone, Debug)]
pub struct ConfigArgs {
#[clap(long = "prover-config-file")]
pub prover_config_file: Option<PathBuf>,
#[clap(long = "parameter-file")]
pub parameter_file: Option<PathBuf>,
#[clap(long = "output-file")]
output_file: Option<PathBuf>,
}

impl ConfigArgs {
pub fn output_file(&self) -> Cow<PathBuf> {
match self.output_file.as_ref() {
Some(path) => Cow::Borrowed(path),
None => Cow::Owned(Path::new("proof.json").to_path_buf()),
}
}
}

#[derive(Args, Clone, Debug)]
pub struct VerifyArgs {
pub proof_file: PathBuf,
}
5 changes: 5 additions & 0 deletions src/commands/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pub mod prove;
pub mod verify;

pub use prove::prove;
pub use verify::verify;
Loading

0 comments on commit 0d014d4

Please sign in to comment.