1
0
Fork 0
mirror of synced 2025-09-23 12:18:44 +00:00
ZoKrates/zokrates_cli/src/bin.rs
2021-07-29 11:13:54 +02:00

227 lines
7.9 KiB
Rust

#![feature(panic_info_message)]
#![feature(backtrace)]
//
// @file bin.rs
// @author Jacob Eberhardt <jacob.eberhardt@tu-berlin.de>
// @author Dennis Kuhnert <dennis.kuhnert@campus.tu-berlin.de>
// @date 2017
#[macro_use]
extern crate lazy_static;
mod constants;
mod helpers;
mod ops;
use clap::{App, AppSettings, Arg};
use ops::*;
fn main() {
// set a custom panic hook
std::panic::set_hook(Box::new(panic_hook));
env_logger::init();
cli().unwrap_or_else(|e| {
println!("{}", e);
std::process::exit(1);
})
}
fn cli() -> Result<(), String> {
// cli specification using clap library
let matches = App::new("ZoKrates")
.setting(AppSettings::SubcommandRequiredElseHelp)
.version(env!("CARGO_PKG_VERSION"))
.author("Jacob Eberhardt, Thibaut Schaeffer, Stefan Deml, Darko Macesic")
.about("Supports generation of zkSNARKs from high level language code including Smart Contracts for proof verification on the Ethereum Blockchain.\n'I know that I show nothing!'")
.arg(Arg::with_name("verbose")
.long("verbose")
.help("Verbose mode")
.required(false)
.global(true)
)
.subcommands(vec![
compile::subcommand(),
check::subcommand(),
compute_witness::subcommand(),
#[cfg(feature = "ark")]
universal_setup::subcommand(),
#[cfg(any(feature = "bellman", feature = "ark", feature = "libsnark"))]
setup::subcommand(),
export_verifier::subcommand(),
#[cfg(any(feature = "bellman", feature = "ark", feature = "libsnark"))]
generate_proof::subcommand(),
generate_smtlib2::subcommand(),
print_proof::subcommand(),
#[cfg(any(feature = "bellman", feature = "ark", feature = "libsnark"))]
verify::subcommand()])
.get_matches();
match matches.subcommand() {
("compile", Some(sub_matches)) => compile::exec(sub_matches),
("check", Some(sub_matches)) => check::exec(sub_matches),
("compute-witness", Some(sub_matches)) => compute_witness::exec(sub_matches),
#[cfg(feature = "ark")]
("universal-setup", Some(sub_matches)) => universal_setup::exec(sub_matches),
#[cfg(any(feature = "bellman", feature = "ark", feature = "libsnark"))]
("setup", Some(sub_matches)) => setup::exec(sub_matches),
("export-verifier", Some(sub_matches)) => export_verifier::exec(sub_matches),
#[cfg(any(feature = "bellman", feature = "ark", feature = "libsnark"))]
("generate-proof", Some(sub_matches)) => generate_proof::exec(sub_matches),
("generate-smtlib2", Some(sub_matches)) => generate_smtlib2::exec(sub_matches),
("print-proof", Some(sub_matches)) => print_proof::exec(sub_matches),
#[cfg(any(feature = "bellman", feature = "ark", feature = "libsnark"))]
("verify", Some(sub_matches)) => verify::exec(sub_matches),
_ => unreachable!(),
}
}
fn panic_hook(pi: &std::panic::PanicInfo) {
let location = pi
.location()
.map(|l| format!("({})", l))
.unwrap_or_default();
let message = pi
.message()
.map(|m| format!("{}", m))
.or_else(|| pi.payload().downcast_ref::<&str>().map(|p| p.to_string()));
if let Some(s) = message {
println!("{} {}", s, location);
} else {
println!("The compiler unexpectedly panicked {}", location);
}
#[cfg(debug_assertions)]
{
use std::backtrace::{Backtrace, BacktraceStatus};
let backtrace = Backtrace::capture();
if backtrace.status() == BacktraceStatus::Captured {
println!("rust backtrace:\n{}", backtrace);
}
}
println!("This is unexpected, please submit a full bug report at https://github.com/Zokrates/ZoKrates/issues");
}
#[cfg(test)]
mod tests {
extern crate glob;
use self::glob::glob;
use std::fs::File;
use std::io::{BufReader, Read};
use std::string::String;
use zokrates_core::compile::{compile, CompilationArtifacts, CompileConfig};
use zokrates_core::ir;
use zokrates_field::Bn128Field;
use zokrates_fs_resolver::FileSystemResolver;
#[test]
fn compile_examples() {
let builder = std::thread::Builder::new().stack_size(8388608);
builder
.spawn(|| {
for p in glob("./examples/**/*").expect("Failed to read glob pattern") {
let path = match p {
Ok(x) => x,
Err(why) => panic!("Error: {:?}", why),
};
if !path.is_file() {
continue;
}
println!("Testing {:?}", path);
assert!(path.extension().expect("extension expected") == "zok");
let should_error = path.to_str().unwrap().contains("compile_errors");
let file = File::open(path.clone()).unwrap();
let mut reader = BufReader::new(file);
let mut source = String::new();
reader.read_to_string(&mut source).unwrap();
let stdlib = std::fs::canonicalize("../zokrates_stdlib/stdlib").unwrap();
let resolver = FileSystemResolver::with_stdlib_root(stdlib.to_str().unwrap());
let res = compile::<Bn128Field, _>(
source,
path,
Some(&resolver),
&CompileConfig::default(),
);
assert_eq!(res.is_err(), should_error);
}
})
.unwrap()
.join()
.unwrap();
}
#[test]
fn execute_examples_ok() {
//these examples should compile and run
for p in glob("./examples/test*").expect("Failed to read glob pattern") {
let path = match p {
Ok(x) => x,
Err(why) => panic!("Error: {:?}", why),
};
println!("Testing {:?}", path);
let file = File::open(path.clone()).unwrap();
let mut reader = BufReader::new(file);
let mut source = String::new();
reader.read_to_string(&mut source).unwrap();
let stdlib = std::fs::canonicalize("../zokrates_stdlib/stdlib").unwrap();
let resolver = FileSystemResolver::with_stdlib_root(stdlib.to_str().unwrap());
let artifacts: CompilationArtifacts<Bn128Field> =
compile(source, path, Some(&resolver), &CompileConfig::default()).unwrap();
let interpreter = ir::Interpreter::default();
let _ = interpreter
.execute(&artifacts.prog(), &[Bn128Field::from(0)])
.unwrap();
}
}
#[test]
fn execute_examples_err() {
//these examples should compile but not run
for p in glob("./examples/runtime_errors/*").expect("Failed to read glob pattern") {
let path = match p {
Ok(x) => x,
Err(why) => panic!("Error: {:?}", why),
};
println!("Testing {:?}", path);
let file = File::open(path.clone()).unwrap();
let mut reader = BufReader::new(file);
let mut source = String::new();
reader.read_to_string(&mut source).unwrap();
let stdlib = std::fs::canonicalize("../zokrates_stdlib/stdlib").unwrap();
let resolver = FileSystemResolver::with_stdlib_root(stdlib.to_str().unwrap());
let artifacts: CompilationArtifacts<Bn128Field> =
compile(source, path, Some(&resolver), &CompileConfig::default()).unwrap();
let interpreter = ir::Interpreter::default();
let res = interpreter.execute(&artifacts.prog(), &[Bn128Field::from(0)]);
assert!(res.is_err());
}
}
}