mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-24 02:31:44 +03:00
Merge pull request #18 from AleoHQ/fix/build
Fixes 'leo build' to compile programs again. Updates tests to run on …
This commit is contained in:
commit
1674149c42
@ -4,7 +4,7 @@ use crate::{
|
||||
ast,
|
||||
constraints::{generate_constraints, ConstrainedValue},
|
||||
errors::CompilerError,
|
||||
InputValue, Program,
|
||||
InputValue, Program
|
||||
};
|
||||
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
@ -28,15 +28,20 @@ pub struct Compiler<F: Field + PrimeField, G: Group> {
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: Group> Compiler<F, G> {
|
||||
pub fn init(package_name: String, main_file_path: PathBuf) -> Self {
|
||||
Self {
|
||||
pub fn init(package_name: String, main_file_path: PathBuf) -> Result<Self, CompilerError> {
|
||||
let mut program = Self {
|
||||
package_name,
|
||||
main_file_path,
|
||||
program: Program::new(),
|
||||
program_inputs: vec![],
|
||||
output: None,
|
||||
_engine: PhantomData,
|
||||
}
|
||||
};
|
||||
|
||||
// Generate the abstract syntax tree and assemble the program
|
||||
program.parse_program()?;
|
||||
|
||||
Ok(program)
|
||||
}
|
||||
|
||||
pub fn checksum(&self) -> Result<String, CompilerError> {
|
||||
@ -52,6 +57,17 @@ impl<F: Field + PrimeField, G: Group> Compiler<F, G> {
|
||||
Ok(hex::encode(hash))
|
||||
}
|
||||
|
||||
pub fn compile_constraints<CS: ConstraintSystem<F>>(
|
||||
self,
|
||||
cs: &mut CS,
|
||||
) -> Result<ConstrainedValue<F, G>, SynthesisError> {
|
||||
let result = generate_constraints(cs, self.program, self.program_inputs).unwrap();
|
||||
|
||||
// Write results to file or something
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
// pub fn compile(&self) -> Result<ast::File, CompilerError> {
|
||||
// // Read in the main file as string
|
||||
// let unparsed_file = fs::read_to_string(&self.main_file_path).map_err(|_| CompilerError::FileReadError(self.main_file_path.clone()))?;
|
||||
@ -66,7 +82,7 @@ impl<F: Field + PrimeField, G: Group> Compiler<F, G> {
|
||||
// Ok(syntax_tree)
|
||||
// }
|
||||
|
||||
pub fn evaluate_program<CS: ConstraintSystem<F>>(&mut self) -> Result<(), CompilerError> {
|
||||
fn parse_program(&mut self) -> Result<(), CompilerError> {
|
||||
// Read in the main file as string
|
||||
let unparsed_file = fs::read_to_string(&self.main_file_path)
|
||||
.map_err(|_| CompilerError::FileReadError(self.main_file_path.clone()))?;
|
||||
@ -85,7 +101,7 @@ impl<F: Field + PrimeField, G: Group> Compiler<F, G> {
|
||||
self.program = Program::<F, G>::from(syntax_tree, package_name);
|
||||
self.program_inputs = vec![None; self.program.num_parameters];
|
||||
|
||||
log::debug!("Compilation complete\n{:#?}", self.program);
|
||||
log::debug!("Program parsing complete\n{:#?}", self.program);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -96,7 +112,7 @@ impl<F: Field + PrimeField, G: Group> ConstraintSynthesizer<F> for Compiler<F, G
|
||||
self,
|
||||
cs: &mut CS,
|
||||
) -> Result<(), SynthesisError> {
|
||||
let _res = generate_constraints(cs, self.program, self.program_inputs).unwrap();
|
||||
let _result = generate_constraints(cs, self.program, self.program_inputs).unwrap();
|
||||
|
||||
// Write results to file or something
|
||||
|
||||
|
@ -8,6 +8,9 @@ pub enum CompilerError {
|
||||
#[error("creating: {}", _0)]
|
||||
Creating(io::Error),
|
||||
|
||||
#[error("Attempt to access current directory failed - {:?}", _0)]
|
||||
DirectoryError(io::Error),
|
||||
|
||||
#[error("{}", _0)]
|
||||
ImportError(ImportError),
|
||||
|
||||
|
@ -1,15 +1,18 @@
|
||||
use leo_compiler::{compiler::Compiler, ConstrainedValue};
|
||||
|
||||
use snarkos_curves::bls12_377::Fr;
|
||||
use leo_compiler::{compiler::Compiler, errors::CompilerError, types::Integer, ConstrainedValue};
|
||||
|
||||
use snarkos_curves::{
|
||||
bls12_377::{Bls12_377, Fr},
|
||||
edwards_bls12::EdwardsProjective
|
||||
};
|
||||
use snarkos_models::gadgets::r1cs::{ConstraintSynthesizer, TestConstraintSystem};
|
||||
use snarkos_models::gadgets::utilities::uint32::UInt32;
|
||||
|
||||
use std::env::current_dir;
|
||||
|
||||
const DIRECTORY_NAME: &str = "tests/u32/";
|
||||
|
||||
fn compile_program(directory_name: &str, file_name: &str) -> Compiler<Fr> {
|
||||
let path = current_dir().unwrap();
|
||||
fn compile_program(directory_name: &str, file_name: &str) -> Result<Compiler<Fr, EdwardsProjective>, CompilerError> {
|
||||
let path = current_dir().map_err(|error| CompilerError::DirectoryError(error))?;
|
||||
|
||||
// Sanitize the package path to the test directory
|
||||
let mut package_path = path.clone();
|
||||
@ -25,69 +28,63 @@ fn compile_program(directory_name: &str, file_name: &str) -> Compiler<Fr> {
|
||||
println!("Compiling file - {:?}", main_file_path);
|
||||
|
||||
// Compile from the main file path
|
||||
let program = Compiler::<Fr>::init(file_name.to_string(), main_file_path);
|
||||
|
||||
program
|
||||
Compiler::<Fr, EdwardsProjective>::init(file_name.to_string(), main_file_path)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_zero() {
|
||||
let mut cs = TestConstraintSystem::<Fr>::new();
|
||||
let program = compile_program(DIRECTORY_NAME, "zero.leo");
|
||||
let output = program.evaluate_program(&mut cs);
|
||||
assert!(cs.is_satisfied());
|
||||
let program = compile_program(DIRECTORY_NAME, "zero.leo").unwrap();
|
||||
let output = program.compile_constraints(&mut cs).unwrap();
|
||||
println!("{}", output);
|
||||
|
||||
let output = output.unwrap();
|
||||
assert!(cs.is_satisfied());
|
||||
assert_eq!(
|
||||
ConstrainedValue::<Fr>::Return(vec![ConstrainedValue::<Fr>::Integer(UInt32::constant(0))]),
|
||||
ConstrainedValue::<Fr, EdwardsProjective>::Return(vec![ConstrainedValue::Integer(Integer::U32(UInt32::constant(0)))]),
|
||||
output
|
||||
);
|
||||
println!("{}", output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_one() {
|
||||
let mut cs = TestConstraintSystem::<Fr>::new();
|
||||
let program = compile_program(DIRECTORY_NAME, "one.leo");
|
||||
let output = program.evaluate_program(&mut cs);
|
||||
assert!(cs.is_satisfied());
|
||||
let program = compile_program(DIRECTORY_NAME, "one.leo").unwrap();
|
||||
let output = program.compile_constraints(&mut cs).unwrap();
|
||||
println!("{}", output);
|
||||
|
||||
let output = output.unwrap();
|
||||
assert!(cs.is_satisfied());
|
||||
assert_eq!(
|
||||
ConstrainedValue::<Fr>::Return(vec![ConstrainedValue::<Fr>::Integer(UInt32::constant(1))]),
|
||||
ConstrainedValue::<Fr, EdwardsProjective>::Return(vec![ConstrainedValue::Integer(Integer::U32(UInt32::constant(1)))]),
|
||||
output
|
||||
);
|
||||
println!("{}", output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_1_plus_1() {
|
||||
let mut cs = TestConstraintSystem::<Fr>::new();
|
||||
let program = compile_program(DIRECTORY_NAME, "1+1.leo");
|
||||
let output = program.evaluate_program(&mut cs);
|
||||
assert!(cs.is_satisfied());
|
||||
let program = compile_program(DIRECTORY_NAME, "1+1.leo").unwrap();
|
||||
let output = program.compile_constraints(&mut cs).unwrap();
|
||||
println!("{}", output);
|
||||
|
||||
let output = output.unwrap();
|
||||
assert!(cs.is_satisfied());
|
||||
assert_eq!(
|
||||
ConstrainedValue::<Fr>::Return(vec![ConstrainedValue::<Fr>::Integer(UInt32::constant(2))]),
|
||||
ConstrainedValue::<Fr, EdwardsProjective>::Return(vec![ConstrainedValue::Integer(Integer::U32(UInt32::constant(2)))]),
|
||||
output
|
||||
);
|
||||
println!("{}", output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_1_minus_1() {
|
||||
let mut cs = TestConstraintSystem::<Fr>::new();
|
||||
let program = compile_program(DIRECTORY_NAME, "1-1.leo");
|
||||
let output = program.evaluate_program(&mut cs);
|
||||
assert!(cs.is_satisfied());
|
||||
let program = compile_program(DIRECTORY_NAME, "1-1.leo").unwrap();
|
||||
let output = program.compile_constraints(&mut cs).unwrap();
|
||||
println!("{}", output);
|
||||
|
||||
let output = output.unwrap();
|
||||
assert!(cs.is_satisfied());
|
||||
assert_eq!(
|
||||
ConstrainedValue::<Fr>::Return(vec![ConstrainedValue::<Fr>::Integer(UInt32::constant(0))]),
|
||||
ConstrainedValue::<Fr, EdwardsProjective>::Return(vec![ConstrainedValue::Integer(Integer::U32(UInt32::constant(0)))]),
|
||||
output
|
||||
);
|
||||
println!("{}", output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -95,7 +92,7 @@ fn test_1_minus_2_should_fail() {
|
||||
// TODO (howardwu): Catch panic from subtraction overflow
|
||||
|
||||
let mut cs = TestConstraintSystem::<Fr>::new();
|
||||
let program = compile_program(DIRECTORY_NAME, "1-2.leo");
|
||||
let output = program.evaluate_program(&mut cs);
|
||||
let program = compile_program(DIRECTORY_NAME, "1-2.leo").unwrap();
|
||||
let output = program.compile_constraints(&mut cs);
|
||||
assert!(output.is_err());
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// The 'pedersen_hash' main function.
|
||||
function main() -> u32 {
|
||||
let a = 1 + 1;
|
||||
let a = 1 / 0;
|
||||
return a
|
||||
}
|
||||
|
@ -63,14 +63,29 @@ impl CLI for BuildCommand {
|
||||
main_file_path.push(MAIN_FILE_NAME);
|
||||
|
||||
// Compute the current program checksum
|
||||
let mut program = Compiler::<Fr, EdwardsProjective>::init(package_name.clone(), main_file_path.clone());
|
||||
let checksum = program.checksum()?;
|
||||
let program = Compiler::<Fr, EdwardsProjective>::init(package_name.clone(), main_file_path.clone())?;
|
||||
let program_checksum = program.checksum()?;
|
||||
|
||||
// Generate the program on the constraint system and verify correctness
|
||||
{
|
||||
let mut cs = KeypairAssembly::<Bls12_377> {
|
||||
num_inputs: 0,
|
||||
num_aux: 0,
|
||||
num_constraints: 0,
|
||||
at: vec![],
|
||||
bt: vec![],
|
||||
ct: vec![],
|
||||
};
|
||||
let temporary_program = program.clone();
|
||||
let output = temporary_program.compile_constraints(&mut cs).unwrap();
|
||||
log::debug!("Compiled constraints - {:#?}", output);
|
||||
}
|
||||
|
||||
// If a checksum file exists, check if it differs from the new checksum
|
||||
let checksum_file = ChecksumFile::new(&package_name);
|
||||
let checksum_differs = if checksum_file.exists_at(&package_path) {
|
||||
let previous_checksum = checksum_file.read_from(&package_path)?;
|
||||
checksum != previous_checksum
|
||||
program_checksum != previous_checksum
|
||||
} else {
|
||||
// By default, the checksum differs if there is no checksum to compare against
|
||||
true
|
||||
@ -79,19 +94,8 @@ impl CLI for BuildCommand {
|
||||
// If checksum differs, compile the program
|
||||
if checksum_differs {
|
||||
// Write the new checksum to the outputs directory
|
||||
checksum_file.write_to(&path, checksum)?;
|
||||
|
||||
// Generate the program on the constraint system and verify correctness
|
||||
// let mut cs = KeypairAssembly::<Bls12_377> {
|
||||
// num_inputs: 0,
|
||||
// num_aux: 0,
|
||||
// num_constraints: 0,
|
||||
// at: vec![],
|
||||
// bt: vec![],
|
||||
// ct: vec![],
|
||||
// };
|
||||
checksum_file.write_to(&path, program_checksum)?;
|
||||
}
|
||||
program.evaluate_program::<KeypairAssembly::<Bls12_377>>()?;
|
||||
|
||||
log::info!("Compiled program in {:?}", main_file_path);
|
||||
|
||||
|
@ -138,6 +138,12 @@ impl From<leo_compiler::errors::CompilerError> for CLIError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<snarkos_errors::gadgets::SynthesisError> for CLIError {
|
||||
fn from(error: snarkos_errors::gadgets::SynthesisError) -> Self {
|
||||
CLIError::Crate("snarkos_errors", format!("{}", error))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<serde_json::error::Error> for CLIError {
|
||||
fn from(error: serde_json::error::Error) -> Self {
|
||||
CLIError::Crate("serde_json", format!("{}", error))
|
||||
|
Loading…
Reference in New Issue
Block a user