2021-02-02 07:26:56 +03:00
|
|
|
// Copyright (C) 2019-2021 Aleo Systems Inc.
|
2020-08-18 13:50:26 +03:00
|
|
|
// This file is part of the Leo library.
|
|
|
|
|
|
|
|
// The Leo library is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
|
|
|
|
// The Leo library is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
2020-10-06 15:22:38 +03:00
|
|
|
// allow the use of EdwardsTestCompiler::parse_program_from_string for tests
|
|
|
|
#![allow(deprecated)]
|
|
|
|
|
2020-07-30 10:15:14 +03:00
|
|
|
pub mod address;
|
2020-07-30 10:56:17 +03:00
|
|
|
pub mod array;
|
2020-07-30 06:52:37 +03:00
|
|
|
pub mod boolean;
|
2020-08-13 22:11:56 +03:00
|
|
|
pub mod circuits;
|
2020-12-11 21:31:13 +03:00
|
|
|
pub mod compiler;
|
2020-08-17 02:10:07 +03:00
|
|
|
pub mod console;
|
2020-09-16 23:41:50 +03:00
|
|
|
pub mod core;
|
2020-08-06 08:45:52 +03:00
|
|
|
pub mod definition;
|
2020-08-17 05:52:33 +03:00
|
|
|
// pub mod field;
|
2020-07-30 22:10:33 +03:00
|
|
|
pub mod function;
|
2020-08-17 05:52:33 +03:00
|
|
|
// pub mod group;
|
2020-07-30 23:01:04 +03:00
|
|
|
pub mod import;
|
2020-07-31 04:17:55 +03:00
|
|
|
pub mod input_files;
|
2020-08-13 22:11:56 +03:00
|
|
|
pub mod integers;
|
|
|
|
pub mod mutability;
|
2020-07-31 03:11:58 +03:00
|
|
|
pub mod statements;
|
2020-07-31 03:19:10 +03:00
|
|
|
pub mod syntax;
|
2020-08-11 05:40:49 +03:00
|
|
|
pub mod tuples;
|
2020-05-19 22:01:19 +03:00
|
|
|
|
2021-02-25 18:40:47 +03:00
|
|
|
use leo_asg::{new_alloc_context, new_context, AsgContext};
|
2020-10-31 03:31:09 +03:00
|
|
|
use leo_ast::{InputValue, MainInput};
|
2020-06-02 04:35:43 +03:00
|
|
|
use leo_compiler::{
|
2020-06-03 02:06:25 +03:00
|
|
|
compiler::Compiler,
|
2020-07-30 09:32:21 +03:00
|
|
|
errors::CompilerError,
|
2020-07-08 05:53:37 +03:00
|
|
|
group::targets::edwards_bls12::EdwardsGroupType,
|
2020-06-02 04:35:43 +03:00
|
|
|
ConstrainedValue,
|
2020-07-30 06:52:37 +03:00
|
|
|
OutputBytes,
|
2020-06-02 04:35:43 +03:00
|
|
|
};
|
2020-08-06 04:13:50 +03:00
|
|
|
use leo_input::types::{IntegerType, U32Type, UnsignedIntegerType};
|
2020-05-19 22:01:19 +03:00
|
|
|
|
2020-12-30 19:40:45 +03:00
|
|
|
use snarkvm_curves::edwards_bls12::Fq;
|
|
|
|
use snarkvm_models::gadgets::r1cs::TestConstraintSystem;
|
2020-07-30 06:52:37 +03:00
|
|
|
|
2020-07-30 09:32:21 +03:00
|
|
|
use std::path::PathBuf;
|
2020-07-30 06:52:37 +03:00
|
|
|
|
2020-08-01 07:15:33 +03:00
|
|
|
pub const TEST_OUTPUT_DIRECTORY: &str = "/output/";
|
2020-07-30 04:32:35 +03:00
|
|
|
const EMPTY_FILE: &str = "";
|
|
|
|
|
2021-02-11 19:38:08 +03:00
|
|
|
pub type EdwardsTestCompiler = Compiler<'static, Fq, EdwardsGroupType>;
|
|
|
|
pub type EdwardsConstrainedValue = ConstrainedValue<'static, Fq, EdwardsGroupType>;
|
|
|
|
|
|
|
|
//convenience function for tests, leaks memory
|
|
|
|
pub(crate) fn make_test_context() -> AsgContext<'static> {
|
2021-02-25 18:40:47 +03:00
|
|
|
let allocator = Box::leak(Box::new(new_alloc_context()));
|
|
|
|
new_context(allocator)
|
2021-02-11 19:38:08 +03:00
|
|
|
}
|
2020-05-30 03:34:31 +03:00
|
|
|
|
2020-07-31 04:17:55 +03:00
|
|
|
fn new_compiler() -> EdwardsTestCompiler {
|
|
|
|
let program_name = "test".to_string();
|
|
|
|
let path = PathBuf::from("/test/src/main.leo");
|
2020-08-01 07:15:33 +03:00
|
|
|
let output_dir = PathBuf::from(TEST_OUTPUT_DIRECTORY);
|
2020-07-31 04:17:55 +03:00
|
|
|
|
2021-02-11 19:38:08 +03:00
|
|
|
EdwardsTestCompiler::new(program_name, path, output_dir, make_test_context())
|
2020-07-31 04:17:55 +03:00
|
|
|
}
|
|
|
|
|
2021-02-11 19:38:08 +03:00
|
|
|
pub(crate) fn parse_program<'a>(program_string: &str) -> Result<EdwardsTestCompiler, CompilerError> {
|
2020-07-31 04:17:55 +03:00
|
|
|
let mut compiler = new_compiler();
|
|
|
|
|
2020-12-04 23:34:51 +03:00
|
|
|
compiler.parse_program_from_string(program_string)?;
|
2020-07-31 04:17:55 +03:00
|
|
|
|
|
|
|
Ok(compiler)
|
|
|
|
}
|
|
|
|
|
2021-02-11 19:38:08 +03:00
|
|
|
pub(crate) fn parse_input<'a>(input_string: &str) -> Result<EdwardsTestCompiler, CompilerError> {
|
2020-07-31 04:17:55 +03:00
|
|
|
let mut compiler = new_compiler();
|
2020-09-03 09:23:50 +03:00
|
|
|
let path = PathBuf::new();
|
2020-07-31 04:17:55 +03:00
|
|
|
|
2020-12-04 20:57:08 +03:00
|
|
|
compiler.parse_input(input_string, &path, EMPTY_FILE, &path)?;
|
2020-07-31 04:17:55 +03:00
|
|
|
|
|
|
|
Ok(compiler)
|
|
|
|
}
|
|
|
|
|
2021-02-11 19:38:08 +03:00
|
|
|
pub(crate) fn parse_state<'a>(state_string: &str) -> Result<EdwardsTestCompiler, CompilerError> {
|
2020-07-31 04:17:55 +03:00
|
|
|
let mut compiler = new_compiler();
|
2020-09-03 09:23:50 +03:00
|
|
|
let path = PathBuf::new();
|
2020-07-31 04:17:55 +03:00
|
|
|
|
2020-12-04 20:57:08 +03:00
|
|
|
compiler.parse_input(EMPTY_FILE, &path, state_string, &path)?;
|
2020-07-31 04:17:55 +03:00
|
|
|
|
|
|
|
Ok(compiler)
|
|
|
|
}
|
|
|
|
|
2021-02-11 19:38:08 +03:00
|
|
|
pub(crate) fn parse_input_and_state<'a>(
|
2020-12-04 20:57:08 +03:00
|
|
|
input_string: &str,
|
|
|
|
state_string: &str,
|
2020-07-31 04:17:55 +03:00
|
|
|
) -> Result<EdwardsTestCompiler, CompilerError> {
|
|
|
|
let mut compiler = new_compiler();
|
2020-09-03 09:23:50 +03:00
|
|
|
let path = PathBuf::new();
|
2020-07-31 04:17:55 +03:00
|
|
|
|
2020-12-04 20:57:08 +03:00
|
|
|
compiler.parse_input(input_string, &path, state_string, &path)?;
|
2020-07-31 04:17:55 +03:00
|
|
|
|
|
|
|
Ok(compiler)
|
|
|
|
}
|
|
|
|
|
2021-02-11 19:38:08 +03:00
|
|
|
pub fn parse_program_with_input<'a>(
|
2020-12-04 23:20:59 +03:00
|
|
|
program_string: &str,
|
|
|
|
input_string: &str,
|
2020-07-30 04:32:35 +03:00
|
|
|
) -> Result<EdwardsTestCompiler, CompilerError> {
|
|
|
|
let mut compiler = new_compiler();
|
2020-09-03 09:23:50 +03:00
|
|
|
let path = PathBuf::new();
|
2020-05-20 01:45:40 +03:00
|
|
|
|
2020-12-04 23:20:59 +03:00
|
|
|
compiler.parse_input(input_string, &path, EMPTY_FILE, &path)?;
|
|
|
|
compiler.parse_program_from_string(program_string)?;
|
2020-07-30 04:32:35 +03:00
|
|
|
|
|
|
|
Ok(compiler)
|
2020-06-09 04:39:10 +03:00
|
|
|
}
|
2020-05-19 22:01:19 +03:00
|
|
|
|
2021-02-11 19:38:08 +03:00
|
|
|
pub fn parse_program_with_state<'a>(
|
2020-12-04 20:51:39 +03:00
|
|
|
program_string: &str,
|
|
|
|
state_string: &str,
|
2020-07-31 04:17:55 +03:00
|
|
|
) -> Result<EdwardsTestCompiler, CompilerError> {
|
2020-06-21 01:24:46 +03:00
|
|
|
let mut compiler = new_compiler();
|
2020-09-03 09:23:50 +03:00
|
|
|
let path = PathBuf::new();
|
2020-07-31 04:17:55 +03:00
|
|
|
|
2020-12-04 20:51:39 +03:00
|
|
|
compiler.parse_input(EMPTY_FILE, &path, state_string, &path)?;
|
|
|
|
compiler.parse_program_from_string(program_string)?;
|
2020-05-19 22:01:19 +03:00
|
|
|
|
2020-06-09 03:28:09 +03:00
|
|
|
Ok(compiler)
|
2020-05-19 22:01:19 +03:00
|
|
|
}
|
2020-06-11 21:43:05 +03:00
|
|
|
|
2020-08-01 05:39:30 +03:00
|
|
|
pub fn parse_program_with_input_and_state(
|
2020-12-04 20:57:08 +03:00
|
|
|
program_string: &str,
|
|
|
|
input_string: &str,
|
|
|
|
state_string: &str,
|
2020-07-31 04:17:55 +03:00
|
|
|
) -> Result<EdwardsTestCompiler, CompilerError> {
|
2020-07-31 03:19:10 +03:00
|
|
|
let mut compiler = new_compiler();
|
2020-09-03 09:23:50 +03:00
|
|
|
let path = PathBuf::new();
|
2020-07-31 04:17:55 +03:00
|
|
|
|
2020-12-04 20:57:08 +03:00
|
|
|
compiler.parse_input(input_string, &path, state_string, &path)?;
|
2020-08-03 03:24:31 +03:00
|
|
|
compiler.parse_program_from_string(&program_string)?;
|
2020-07-31 03:19:10 +03:00
|
|
|
|
|
|
|
Ok(compiler)
|
|
|
|
}
|
2020-07-30 04:32:35 +03:00
|
|
|
|
2020-08-01 07:15:33 +03:00
|
|
|
pub(crate) fn get_output(program: EdwardsTestCompiler) -> OutputBytes {
|
2020-07-30 06:52:37 +03:00
|
|
|
// synthesize the circuit on the test constraint system
|
2020-07-30 04:32:35 +03:00
|
|
|
let mut cs = TestConstraintSystem::<Fq>::new();
|
2021-02-05 04:26:29 +03:00
|
|
|
let output = program.compile_constraints(&mut cs).unwrap();
|
2020-07-30 06:52:37 +03:00
|
|
|
|
|
|
|
// assert the constraint system is satisfied
|
2020-07-30 04:32:35 +03:00
|
|
|
assert!(cs.is_satisfied());
|
2020-07-30 06:52:37 +03:00
|
|
|
|
|
|
|
output
|
2020-07-30 04:32:35 +03:00
|
|
|
}
|
|
|
|
|
2020-07-30 06:52:37 +03:00
|
|
|
pub(crate) fn assert_satisfied(program: EdwardsTestCompiler) {
|
2020-08-01 07:15:33 +03:00
|
|
|
let empty_output_bytes = include_bytes!("compiler_output/empty.out");
|
|
|
|
let res = get_output(program);
|
2020-07-30 06:52:37 +03:00
|
|
|
|
|
|
|
// assert that the output is empty
|
|
|
|
assert_eq!(empty_output_bytes, res.bytes().as_slice());
|
|
|
|
}
|
|
|
|
|
2020-07-30 21:11:54 +03:00
|
|
|
pub(crate) fn expect_compiler_error(program: EdwardsTestCompiler) -> CompilerError {
|
2020-07-30 04:32:35 +03:00
|
|
|
let mut cs = TestConstraintSystem::<Fq>::new();
|
2021-02-05 04:26:29 +03:00
|
|
|
program.compile_constraints(&mut cs).unwrap_err()
|
2020-07-30 04:32:35 +03:00
|
|
|
}
|
2020-11-12 21:28:24 +03:00
|
|
|
|
2020-12-17 00:02:31 +03:00
|
|
|
pub(crate) fn expect_asg_error(error: CompilerError) {
|
|
|
|
assert!(matches!(error, CompilerError::AsgConvertError(_)))
|
2020-11-12 01:57:39 +03:00
|
|
|
}
|
2020-10-26 22:55:00 +03:00
|
|
|
|
2020-08-01 05:39:30 +03:00
|
|
|
pub(crate) fn generate_main_input(input: Vec<(&str, Option<InputValue>)>) -> MainInput {
|
|
|
|
let mut main_input = MainInput::new();
|
2020-07-30 09:32:21 +03:00
|
|
|
|
2020-08-01 05:39:30 +03:00
|
|
|
for (name, value) in input {
|
|
|
|
main_input.insert(name.to_string(), value);
|
2020-07-30 04:32:35 +03:00
|
|
|
}
|
2020-07-30 09:32:21 +03:00
|
|
|
|
2020-08-01 05:39:30 +03:00
|
|
|
main_input
|
2020-07-30 04:32:35 +03:00
|
|
|
}
|
2020-08-06 04:13:50 +03:00
|
|
|
|
|
|
|
pub(crate) fn generate_test_input_u32(number: u32) -> Option<InputValue> {
|
|
|
|
Some(InputValue::Integer(
|
|
|
|
IntegerType::Unsigned(UnsignedIntegerType::U32Type(U32Type {})),
|
|
|
|
number.to_string(),
|
|
|
|
))
|
|
|
|
}
|