Skip to content

Commit 3b5b91c

Browse files
feat: CLI prove use bin name for output path + e2e stark verify (#1675)
Resolves INT-4074. Primarily accomplishes the following: - `cargo openvm prove` outputs proofs to `${bin_name}.app.proof` instead of `app.proof`, where `bin_name` is the file stem of the executable (same for `stark` and `evm`) - `cargo openvm verify` by default searches the working directory for files with extension `.app.proof` Additionally, the following are also in this PR: - `cargo openvm init ${dir}` creates directory `dir` if it doesn't already exist - Updates to the book to reflect recent CLI changes The following were merged from #1689: - SDK functionality to verify e2e STARK proofs - `cargo openvm verify stark` subcommand
1 parent b6d3533 commit 3b5b91c

File tree

15 files changed

+250
-124
lines changed

15 files changed

+250
-124
lines changed

book/src/getting-started/quickstart.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ In this section we will build and run a fibonacci program.
77
First, create a new Rust project.
88

99
```bash
10-
cargo init fibonacci
10+
cargo openvm init fibonacci
1111
```
1212

13-
In `Cargo.toml`, add the following dependency:
13+
This will generate an OpenVM-specific starter package. Notice `Cargo.toml` has the following dependency:
1414

1515
```toml
1616
[dependencies]
@@ -49,7 +49,7 @@ To build the program, run:
4949
cargo openvm build
5050
```
5151

52-
This will output an OpenVM executable file to `./openvm/app.vmexe`.
52+
This will output an OpenVM executable file to `./target/openvm/release/fibonacci.vmexe`.
5353

5454
## Keygen
5555

@@ -59,7 +59,7 @@ Before generating any proofs, we will also need to generate the proving and veri
5959
cargo openvm keygen
6060
```
6161

62-
This will output a serialized proving key to `./openvm/app.pk` and a verification key to `./openvm/app.vk`.
62+
This will output a serialized proving key to `./target/openvm/app.pk` and a verification key to `./target/openvm/app.vk`.
6363

6464
## Proof Generation
6565

@@ -72,7 +72,7 @@ OPENVM_FAST_TEST=1 cargo openvm prove app --input "0x010A00000000000000"
7272
The `--input` field is passed to the program which receives it via the `io::read` function.
7373
In our `main.rs` we called `read()` to get `n: u64`. The input here is `n = 10u64` _in little endian_. Note that this value must be padded to exactly 8 bytes (64 bits) and is prefixed with `0x01` to indicate that the input is composed of raw bytes.
7474

75-
The serialized proof will be output to `./openvm/app.proof`.
75+
The serialized proof will be output to `./fibonacci.app.proof`.
7676

7777
The `OPENVM_FAST_TEST` environment variable is used to enable fast proving for testing purposes. To run with proof with secure parameters, remove the environmental variable.
7878

book/src/writing-apps/overview.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ cargo openvm run --input <path_to_input | hex_string>
2222

2323
Note if your program doesn't require inputs, you can omit the `--input` flag.
2424

25-
For more information on both commands, see the [build](./build.md) docs.
25+
For more information see the [build](./build.md) and [run](./run.md) docs.
2626

2727
### Inputs
2828

book/src/writing-apps/prove.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,7 @@ If `--exe` is not provided, the command will call `build` before generating a pr
4040

4141
If your program doesn't require inputs, you can (and should) omit the `--input` flag.
4242

43-
If `--proof` is not provided then the command will write the proof to `./[app | stark | evm].proof` by default.
44-
43+
If `--proof` is not provided then the command will write the proof to `./${bin_name}.[app | stark | evm].proof` by default, where `bin_name` is the file stem of the executable run.
4544

4645
The `app` subcommand generates an application-level proof, the `stark` command generates an aggregated root-level proof, while the `evm` command generates an end-to-end EVM proof. For more information on aggregation, see [this specification](https://github.com/openvm-org/openvm/blob/bf8df90b13f4e80bb76dbb71f255a12154c84838/docs/specs/continuations.md).
4746

book/src/writing-apps/verify.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ cargo openvm verify app
1010
--proof <path_to_proof>
1111
```
1212

13-
Options `--manifest-path`, `--target-dir` are also available to `verify`. If you omit `--app_vk` and/or `--proof`, the command will search for those files at `${target_dir}/openvm/app.vk` and `./app.proof` respectively.
13+
Options `--manifest-path`, `--target-dir` are also available to `verify`. If you omit `--app_vk` the command will search for the verifying key at `${target_dir}/openvm/app.vk`.
14+
15+
If you omit `--proof`, the command will search the working directory for files with the `.app.proof` extension. Note that for this default case a single proof is expected to be found, and `verify` will fail otherwise.
1416

1517
## EVM Level
1618

@@ -93,11 +95,11 @@ cargo openvm prove evm --input <path_to_input>
9395
cargo openvm verify evm --proof <path_to_proof>
9496
```
9597

96-
If `proof` is omitted, the `verify` command will search for the proof at `./openvm/evm.proof`.
98+
If `proof` is omitted, the `verify` command will search for a file with extension `.evm.proof` in the working directory.
9799

98100
### EVM Proof: JSON Format
99101

100-
The EVM proof is written to `evm.proof` as a JSON of the following format:
102+
The EVM proof is written as a JSON of the following format:
101103

102104
```json
103105
{

book/src/writing-apps/write-program.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,17 @@
22

33
## Writing a guest program
44

5-
See the example [fibonacci program](https://github.com/openvm-org/openvm-example-fibonacci).
5+
To initialize an OpenVM guest program package, you can use the following CLI command:
66

7-
The guest program should be a `no_std` Rust crate. As long as it is `no_std`, you can import any other
8-
`no_std` crates and write Rust as you normally would. Import the `openvm` library crate to use `openvm` intrinsic functions (for example `openvm::io::*`).
7+
```bash
8+
cargo openvm init
9+
```
910

10-
More examples of guest programs can be found in the [benchmarks/guest](https://github.com/openvm-org/openvm/tree/main/benchmarks/guest) directory.
11+
For a guest program example, see this [fibonacci program](https://github.com/openvm-org/openvm-example-fibonacci). More examples can be found in the [benchmarks/guest](https://github.com/openvm-org/openvm/tree/main/benchmarks/guest) directory.
1112

1213
## Handling I/O
1314

14-
The program can take input from stdin, with some functions provided by `openvm::io`.
15+
The program can take input from stdin, with some functions provided by `openvm::io`. Make sure to import the `openvm` library crate to use `openvm` intrinsic functions.
1516

1617
`openvm::io::read` takes from stdin and deserializes it into a generic type `T`, so one should specify the type when calling it:
1718

crates/cli/src/commands/commit.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@ use openvm_sdk::{commit::AppExecutionCommit, fs::write_to_file_json, Sdk};
1111
use super::{RunArgs, RunCargoArgs};
1212
use crate::{
1313
commands::{load_app_pk, load_or_build_and_commit_exe},
14-
util::{
15-
get_manifest_path_and_dir, get_single_target_name, get_target_dir, get_target_output_dir,
16-
},
14+
util::{get_manifest_path_and_dir, get_target_dir, get_target_output_dir},
1715
};
1816

1917
#[derive(Parser)]
@@ -76,7 +74,7 @@ impl CommitCmd {
7674
init_file_name: self.init_file_name.clone(),
7775
input: None,
7876
};
79-
let committed_exe =
77+
let (committed_exe, target_name) =
8078
load_or_build_and_commit_exe(&sdk, &run_args, &self.cargo_args, &app_pk)?;
8179

8280
let commits = AppExecutionCommit::compute(
@@ -91,7 +89,6 @@ impl CommitCmd {
9189
let (manifest_path, _) = get_manifest_path_and_dir(&self.cargo_args.manifest_path)?;
9290
let target_dir = get_target_dir(&self.cargo_args.target_dir, &manifest_path);
9391
let target_output_dir = get_target_output_dir(&target_dir, &self.cargo_args.profile);
94-
let target_name = get_single_target_name(&self.cargo_args)?;
9592

9693
let commit_name = format!("{}.commit.json", &target_name);
9794
let commit_path = target_output_dir.join(&commit_name);

crates/cli/src/commands/init.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,10 @@ impl InitCmd {
113113
.path
114114
.clone()
115115
.unwrap_or(PathBuf::from(".").canonicalize()?);
116+
args.push(path.to_str().unwrap());
116117

117118
let mut cmd = Command::new("cargo");
118119
cmd.args(&args);
119-
cmd.current_dir(&path);
120120

121121
let status = cmd.status()?;
122122
if !status.success() {

crates/cli/src/commands/prove.rs

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ use openvm_sdk::{
1616
};
1717

1818
use super::{RunArgs, RunCargoArgs};
19-
#[cfg(feature = "evm-prove")]
20-
use crate::util::read_default_agg_pk;
2119
use crate::{
2220
commands::build,
23-
default::*,
21+
default::default_agg_stark_pk_path,
2422
input::read_to_stdin,
2523
util::{get_app_pk_path, get_manifest_path_and_dir, get_single_target_name, get_target_dir},
2624
};
25+
#[cfg(feature = "evm-prove")]
26+
use crate::{default::default_params_dir, util::read_default_agg_pk};
2727

2828
#[derive(Parser)]
2929
#[command(name = "prove", about = "Generate a program proof")]
@@ -38,11 +38,10 @@ enum ProveSubCommand {
3838
#[arg(
3939
long,
4040
action,
41-
default_value = DEFAULT_APP_PROOF_PATH,
42-
help = "Path to app proof output",
41+
help = "Path to app proof output, by default will be ./${bin_name}.app.proof",
4342
help_heading = "Output"
4443
)]
45-
proof: PathBuf,
44+
proof: Option<PathBuf>,
4645

4746
#[arg(
4847
long,
@@ -62,11 +61,10 @@ enum ProveSubCommand {
6261
#[arg(
6362
long,
6463
action,
65-
default_value = DEFAULT_STARK_PROOF_PATH,
66-
help = "Path to STARK proof output",
64+
help = "Path to STARK proof output, by default will be ./${bin_name}.stark.proof",
6765
help_heading = "Output"
6866
)]
69-
proof: PathBuf,
67+
proof: Option<PathBuf>,
7068

7169
#[arg(
7270
long,
@@ -90,11 +88,10 @@ enum ProveSubCommand {
9088
#[arg(
9189
long,
9290
action,
93-
default_value = DEFAULT_EVM_PROOF_PATH,
94-
help = "Path to EVM proof output",
91+
help = "Path to EVM proof output, by default will be ./${bin_name}.evm.proof",
9592
help_heading = "Output"
9693
)]
97-
proof: PathBuf,
94+
proof: Option<PathBuf>,
9895

9996
#[arg(
10097
long,
@@ -126,12 +123,18 @@ impl ProveCmd {
126123
} => {
127124
let sdk = Sdk::new();
128125
let app_pk = load_app_pk(app_pk, cargo_args)?;
129-
let committed_exe =
126+
let (committed_exe, target_name) =
130127
load_or_build_and_commit_exe(&sdk, run_args, cargo_args, &app_pk)?;
131128

132129
let app_proof =
133130
sdk.generate_app_proof(app_pk, committed_exe, read_to_stdin(&run_args.input)?)?;
134-
write_app_proof_to_file(app_proof, proof)?;
131+
132+
let proof_path = if let Some(proof) = proof {
133+
proof
134+
} else {
135+
&PathBuf::from(format!("{}.app.proof", target_name))
136+
};
137+
write_app_proof_to_file(app_proof, proof_path)?;
135138
}
136139
ProveSubCommand::Stark {
137140
app_pk,
@@ -142,7 +145,7 @@ impl ProveCmd {
142145
} => {
143146
let sdk = Sdk::new().with_agg_tree_config(*agg_tree_config);
144147
let app_pk = load_app_pk(app_pk, cargo_args)?;
145-
let committed_exe =
148+
let (committed_exe, target_name) =
146149
load_or_build_and_commit_exe(&sdk, run_args, cargo_args, &app_pk)?;
147150

148151
let commits = AppExecutionCommit::compute(
@@ -163,7 +166,12 @@ impl ProveCmd {
163166
read_to_stdin(&run_args.input)?,
164167
)?;
165168

166-
encode_to_file(proof, stark_proof)?;
169+
let proof_path = if let Some(proof) = proof {
170+
proof
171+
} else {
172+
&PathBuf::from(format!("{}.stark.proof", target_name))
173+
};
174+
encode_to_file(proof_path, stark_proof)?;
167175
}
168176
#[cfg(feature = "evm-prove")]
169177
ProveSubCommand::Evm {
@@ -177,7 +185,7 @@ impl ProveCmd {
177185

178186
let sdk = Sdk::new().with_agg_tree_config(*agg_tree_config);
179187
let app_pk = load_app_pk(app_pk, cargo_args)?;
180-
let committed_exe =
188+
let (committed_exe, target_name) =
181189
load_or_build_and_commit_exe(&sdk, run_args, cargo_args, &app_pk)?;
182190

183191
let commits = AppExecutionCommit::compute(
@@ -201,7 +209,12 @@ impl ProveCmd {
201209
read_to_stdin(&run_args.input)?,
202210
)?;
203211

204-
write_evm_proof_to_file(evm_proof, proof)?;
212+
let proof_path = if let Some(proof) = proof {
213+
proof
214+
} else {
215+
&PathBuf::from(format!("{}.evm.proof", target_name))
216+
};
217+
write_evm_proof_to_file(evm_proof, proof_path)?;
205218
}
206219
}
207220
Ok(())
@@ -224,12 +237,13 @@ pub(crate) fn load_app_pk(
224237
Ok(Arc::new(read_app_pk_from_file(app_pk_path)?))
225238
}
226239

240+
// Returns (committed_exe, target_name) where target_name has no extension
227241
pub(crate) fn load_or_build_and_commit_exe(
228242
sdk: &Sdk,
229243
run_args: &RunArgs,
230244
cargo_args: &RunCargoArgs,
231245
app_pk: &Arc<AppProvingKey<SdkVmConfig>>,
232-
) -> Result<Arc<NonRootCommittedExe>> {
246+
) -> Result<(Arc<NonRootCommittedExe>, String)> {
233247
let exe_path = if let Some(exe) = &run_args.exe {
234248
exe
235249
} else {
@@ -243,5 +257,8 @@ pub(crate) fn load_or_build_and_commit_exe(
243257

244258
let app_exe = read_exe_from_file(exe_path)?;
245259
let committed_exe = sdk.commit_app_exe(app_pk.app_fri_params(), app_exe)?;
246-
Ok(committed_exe)
260+
Ok((
261+
committed_exe,
262+
exe_path.file_stem().unwrap().to_string_lossy().into_owned(),
263+
))
247264
}

0 commit comments

Comments
 (0)