Skip to content

Commit

Permalink
feat: allow to view the verification key by providing the program name (
Browse files Browse the repository at this point in the history
  • Loading branch information
leruaa authored Nov 16, 2024
1 parent c974b47 commit 20c5f23
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 24 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 17 additions & 7 deletions crates/build/src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ pub fn execute_build_program(

let target_elf_paths = generate_elf_paths(&program_metadata, Some(args))?;

print_elf_paths_cargo_directives(&target_elf_paths);

Ok(target_elf_paths)
}

Expand All @@ -67,7 +69,10 @@ pub(crate) fn build_program_internal(path: &str, args: Option<BuildArgs>) {
.unwrap_or(false);
if skip_program_build {
// Still need to set ELF env vars even if build is skipped.
generate_elf_paths(&metadata, args.as_ref()).expect("failed to collect target ELF paths");
let target_elf_paths = generate_elf_paths(&metadata, args.as_ref())
.expect("failed to collect target ELF paths");

print_elf_paths_cargo_directives(&target_elf_paths);

println!(
"cargo:warning=Build skipped for {} at {} due to SP1_SKIP_PROGRAM_BUILD flag",
Expand All @@ -88,7 +93,10 @@ pub(crate) fn build_program_internal(path: &str, args: Option<BuildArgs>) {
.unwrap_or(false);
if is_clippy_driver {
// Still need to set ELF env vars even if build is skipped.
generate_elf_paths(&metadata, args.as_ref()).expect("failed to collect target ELF paths");
let target_elf_paths = generate_elf_paths(&metadata, args.as_ref())
.expect("failed to collect target ELF paths");

print_elf_paths_cargo_directives(&target_elf_paths);

println!("cargo:warning=Skipping build due to clippy invocation.");
return;
Expand All @@ -107,9 +115,8 @@ pub(crate) fn build_program_internal(path: &str, args: Option<BuildArgs>) {
println!("cargo:warning={} built at {}", root_package_name, current_datetime());
}

/// Collects the list of targets that would be built and their output ELF file paths. Also prints
/// cargo directives setting relevant `SP1_ELF_` environment variables.
fn generate_elf_paths(
/// Collects the list of targets that would be built and their output ELF file paths.
pub fn generate_elf_paths(
metadata: &cargo_metadata::Metadata,
args: Option<&BuildArgs>,
) -> Result<Vec<(String, Utf8PathBuf)>> {
Expand Down Expand Up @@ -164,9 +171,12 @@ fn generate_elf_paths(
}
}

Ok(target_elf_paths)
}

/// Prints cargo directives setting relevant `SP1_ELF_` environment variables.
fn print_elf_paths_cargo_directives(target_elf_paths: &[(String, Utf8PathBuf)]) {
for (target_name, elf_path) in target_elf_paths.iter() {
println!("cargo:rustc-env=SP1_ELF_{}={}", target_name, elf_path);
}

Ok(target_elf_paths)
}
2 changes: 1 addition & 1 deletion crates/build/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ mod build;
mod command;
mod utils;
use build::build_program_internal;
pub use build::execute_build_program;
pub use build::{execute_build_program, generate_elf_paths};

use clap::Parser;

Expand Down
1 change: 1 addition & 0 deletions crates/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,4 @@ regex = "1.5.4"
prettytable-rs = "0.10"
textwrap = "0.16.0"
ctrlc = "3.4.2"
cargo_metadata = "0.18.1"
60 changes: 46 additions & 14 deletions crates/cli/src/commands/vkey.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,63 @@
use std::fs::File;
use std::{fs::File, io::Read};

use anyhow::Result;
use clap::Parser;
use clap::{Args, Parser};
use sp1_build::{generate_elf_paths, BuildArgs};
use sp1_sdk::{HashableKey, ProverClient};
use std::io::Read;

#[derive(Parser)]
#[command(name = "vkey", about = "View the verification key hash for a program.")]
pub struct VkeyCmd {
/// Path to the ELF.
#[arg(long, required = true)]
elf: String,
#[clap(flatten)]
elf: Elf,
}

#[derive(Debug, Clone, Args)]
#[group(required = true, multiple = false)]
pub struct Elf {
/// The path to the ELF file
#[arg(long = "elf")]
path: Option<String>,
/// The crate used to generate the ELF file
#[arg(long)]
program: Option<String>,
}

impl VkeyCmd {
pub fn run(&self) -> Result<()> {
// Read the elf file contents
let mut file = File::open(self.elf.clone()).unwrap();
let mut elf = Vec::new();
file.read_to_end(&mut elf).unwrap();
let elf_paths = if let Some(path) = &self.elf.path {
vec![(None, path.clone())]
} else if let Some(program) = &self.elf.program {
let metadata_cmd = cargo_metadata::MetadataCommand::new();
let metadata = metadata_cmd.exec()?;
let build_args = BuildArgs { packages: vec![program.clone()], ..Default::default() };

generate_elf_paths(&metadata, Some(&build_args))?
.into_iter()
.map(|(target, path)| (Some(target), path.to_string()))
.collect()
} else {
unreachable!()
};

for (target, elf_path) in elf_paths {
// Read the elf file contents
let mut file = File::open(elf_path)?;
let mut elf = Vec::new();
file.read_to_end(&mut elf)?;

// Get the verification key
let prover = ProverClient::new();
let (_, vk) = prover.setup(&elf);
// Get the verification key
let prover = ProverClient::new();
let (_, vk) = prover.setup(&elf);

// Print the verification key hash
println!("Verification Key Hash:\n{}", vk.vk.bytes32());
// Print the verification key hash
if let Some(target) = target {
println!("Verification Key Hash for '{target}':\n{}", vk.vk.bytes32());
} else {
println!("Verification Key Hash:\n{}", vk.vk.bytes32());
}
}

Ok(())
}
Expand Down
4 changes: 2 additions & 2 deletions crates/test-artifacts/programs/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 20c5f23

Please sign in to comment.