Merge pull request #51 from AleoHQ/feature/tooling

Adds build infrastructure and tooling
This commit is contained in:
Collin Chin 2020-06-08 20:03:25 -07:00 committed by GitHub
commit 72016a5608
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
117 changed files with 1395 additions and 1682 deletions

5
.codecov.yml Normal file
View File

@ -0,0 +1,5 @@
coverage:
status:
project:
default:
threshold: 2%

15
.rustfmt.toml Normal file
View File

@ -0,0 +1,15 @@
# https://github.com/rust-lang/rustfmt/blob/master/Configurations.md
# Stable configurations
edition = "2018"
max_width = 120
merge_derives = true
use_field_init_shorthand = true
use_try_shorthand = true
# Nightly configurations
imports_layout = "HorizontalVertical"
merge_imports = true
overflow_delimited_expr = true
reorder_impl_items = true
version = "Two"

5
.rusty-hook.toml Normal file
View File

@ -0,0 +1,5 @@
[hooks]
pre-commit = "cargo +nightly fmt --all -- --check"
[logging]
verbose = false

70
.travis.yml Normal file
View File

@ -0,0 +1,70 @@
language: rust
before_install:
- set -e
- export SCCACHE_CACHE_SIZE=200M
- export SCCACHE_DIR="$TRAVIS_HOME/.cache/sccache"
- mkdir "$TRAVIS_HOME/.bin"
- wget https://github.com/mozilla/sccache/releases/download/0.2.13/sccache-0.2.13-x86_64-unknown-linux-musl.tar.gz
- tar -C "$TRAVIS_HOME/.bin" -xvf sccache-0.2.13-x86_64-unknown-linux-musl.tar.gz
- mv $TRAVIS_HOME/.bin/sccache-0.2.13-x86_64-unknown-linux-musl/sccache $TRAVIS_HOME/.bin/sccache
- export PATH="$PATH:$TRAVIS_HOME/.bin"
- export RUSTC_WRAPPER="sccache"
- |
declare -r SSH_FILE="$(mktemp -u $HOME/.ssh/XXXXX)"
openssl aes-256-cbc -K $encrypted_beefc4a47cdc_key -iv $encrypted_beefc4a47cdc_iv -in .travis/travis-snarkos.enc -out $SSH_FILE -d
chmod 600 "$SSH_FILE" \
&& printf "%s\n" \
"Host github.com" \
" IdentityFile $SSH_FILE" \
" LogLevel ERROR" >> ~/.ssh/config
- git clone --progress --verbose git@github.com:AleoHQ/snarkOS.git
- mv snarkOS ..
cache:
directories:
- $TRAVIS_HOME/.cache/sccache
- $TRAVIS_HOME/.cargo
# See https://levans.fr/rust_travis_cache.html
before_cache:
- rm -rf "$TRAVIS_HOME/.cargo/registry"
after_script:
- (sccache -s||true)
- set +e
matrix:
fast_finish: true
include:
- rust: stable
env: TEST_COVERAGE=1
addons:
apt:
packages:
- libcurl4-openssl-dev
- libelf-dev
- libdw-dev
- cmake
- gcc
- binutils-dev
- libiberty-dev
script:
- cargo test --all
after_success:
- wget https://github.com/SimonKagstrom/kcov/archive/master.tar.gz
- tar xzf master.tar.gz && cd kcov-master
- mkdir build && cd build && cmake .. && make && sudo make install
- cd ../.. && rm -rf kcov-master
- for file in target/debug/deps/*-*; do if [[ "$file" != *\.* ]]; then mkdir -p "target/cov/$(basename $file)"; kcov --exclude-pattern=/.cargo,/usr/lib --verify "target/cov/$(basename $file)" "$file"; fi done
- bash <(curl -s https://codecov.io/bash)
- echo "Uploaded code coverage"
- rust: nightly-2020-03-18
install:
- rustup component add rustfmt
script:
- cargo fmt -- --check
- cargo test --all
script:
- echo "leo"

BIN
.travis/travis-snarkos.enc Normal file

Binary file not shown.

71
Cargo.lock generated
View File

@ -69,9 +69,9 @@ dependencies = [
[[package]]
name = "bindgen"
version = "0.53.2"
version = "0.53.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6bb26d6a69a335b8cb0e7c7e9775cd5666611dc50a37177c3f2cedcfc040e8c8"
checksum = "c72a978d268b1d70b0e963217e60fdabd9523a941457a6c42a7315d15c7e89e5"
dependencies = [
"bitflags",
"cexpr",
@ -166,6 +166,15 @@ version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "ci_info"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a19c5f9baeac8a1176ca7fc58a0cc1abadd84d360365a93d1dd31e926f3f502b"
dependencies = [
"envmnt",
]
[[package]]
name = "clang-sys"
version = "0.29.3"
@ -329,6 +338,16 @@ dependencies = [
"termcolor",
]
[[package]]
name = "envmnt"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fba7e7d8c007e12db7b3bd6f04b8e47e206c9173d9c75413a042ccc941723c8"
dependencies = [
"fsio",
"indexmap",
]
[[package]]
name = "failure"
version = "0.1.7"
@ -367,6 +386,12 @@ dependencies = [
"void",
]
[[package]]
name = "fsio"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2131cb03096f67334dfba2f0bc46afc5564b08a919d042c6e217e2665741fc54"
[[package]]
name = "futures"
version = "0.1.29"
@ -382,6 +407,15 @@ dependencies = [
"typenum",
]
[[package]]
name = "getopts"
version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5"
dependencies = [
"unicode-width",
]
[[package]]
name = "getrandom"
version = "0.1.14"
@ -423,6 +457,15 @@ dependencies = [
"quick-error",
]
[[package]]
name = "indexmap"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c398b2b113b55809ceb9ee3e753fcbac793f1956663f3c36549c1346015c2afe"
dependencies = [
"autocfg",
]
[[package]]
name = "itertools"
version = "0.7.11"
@ -475,6 +518,7 @@ dependencies = [
"log",
"rand",
"rand_core",
"rusty-hook",
"serde",
"serde_json",
"snarkos-algorithms",
@ -510,7 +554,6 @@ dependencies = [
"log",
"rand",
"sha2",
"snarkos-algorithms",
"snarkos-curves",
"snarkos-errors",
"snarkos-gadgets",
@ -605,6 +648,12 @@ dependencies = [
"autocfg",
]
[[package]]
name = "nias"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab250442c86f1850815b5d268639dff018c0627022bc1940eb2d642ca1ce12f0"
[[package]]
name = "nom"
version = "5.1.1"
@ -886,6 +935,18 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rusty-hook"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27138b73a8ce63ae918707a5e3b57f9b0c0842a57b82f0e43474cf4e3aaf0ff4"
dependencies = [
"ci_info",
"getopts",
"nias",
"toml",
]
[[package]]
name = "ryu"
version = "1.0.2"
@ -1219,9 +1280,9 @@ checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
[[package]]
name = "version_check"
version = "0.9.1"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce"
checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
[[package]]
name = "void"

View File

@ -36,3 +36,27 @@ serde = { version = "1.0", features = ["derive"] }
serde_json = { version = "1.0" }
toml = { version = "0.5" }
thiserror = { version = "1.0" }
[dev-dependencies]
rusty-hook = { version = "0.11.1" }
[profile.release]
opt-level = 3
lto = "thin"
incremental = true
[profile.bench]
opt-level = 3
debug = false
rpath = false
lto = "thin"
incremental = true
debug-assertions = false
[profile.dev]
opt-level = 0
[profile.test]
opt-level = 0
debug-assertions = true
debug = true

View File

@ -1,3 +0,0 @@
[package]
name = "language"
version = "0.1.0"

View File

@ -1,4 +1,7 @@
use crate::{access::{ArrayAccess, MemberAccess}, ast::Rule};
use crate::{
access::{ArrayAccess, MemberAccess},
ast::Rule,
};
use pest_ast::FromPest;
use std::fmt;

View File

@ -2,18 +2,15 @@
use crate::{
common::Identifier,
expressions::{
ArrayInlineExpression,
ArrayInitializerExpression,
ArrayInlineExpression,
CircuitInlineExpression,
Expression,
TernaryExpression,
NotExpression,
PostfixExpression
},
operations::{
BinaryOperation,
NotOperation,
PostfixExpression,
TernaryExpression,
},
operations::{BinaryOperation, NotOperation},
values::Value,
};
@ -22,7 +19,8 @@ use pest::{
error::Error,
iterators::{Pair, Pairs},
prec_climber::{Assoc, Operator, PrecClimber},
Parser, Span,
Parser,
Span,
};
#[derive(Parser)]
@ -47,16 +45,13 @@ fn precedence_climber() -> PrecClimber<Rule> {
PrecClimber::new(vec![
Operator::new(Rule::operation_or, Assoc::Left),
Operator::new(Rule::operation_and, Assoc::Left),
Operator::new(Rule::operation_eq, Assoc::Left)
| Operator::new(Rule::operation_ne, Assoc::Left),
Operator::new(Rule::operation_eq, Assoc::Left) | Operator::new(Rule::operation_ne, Assoc::Left),
Operator::new(Rule::operation_ge, Assoc::Left)
| Operator::new(Rule::operation_gt, Assoc::Left)
| Operator::new(Rule::operation_le, Assoc::Left)
| Operator::new(Rule::operation_lt, Assoc::Left),
Operator::new(Rule::operation_add, Assoc::Left)
| Operator::new(Rule::operation_sub, Assoc::Left),
Operator::new(Rule::operation_mul, Assoc::Left)
| Operator::new(Rule::operation_div, Assoc::Left),
Operator::new(Rule::operation_add, Assoc::Left) | Operator::new(Rule::operation_sub, Assoc::Left),
Operator::new(Rule::operation_mul, Assoc::Left) | Operator::new(Rule::operation_div, Assoc::Left),
Operator::new(Rule::operation_pow, Assoc::Left),
])
}
@ -69,55 +64,55 @@ fn parse_term(pair: Pair<Rule>) -> Box<Expression> {
match next.as_rule() {
Rule::expression => Expression::from_pest(&mut pair.into_inner()).unwrap(), // Parenthesis case
Rule::expression_array_inline => {
Expression::ArrayInline(
ArrayInlineExpression::from_pest(&mut pair.into_inner()).unwrap()
)
},
Expression::ArrayInline(ArrayInlineExpression::from_pest(&mut pair.into_inner()).unwrap())
}
Rule::expression_array_initializer => {
Expression::ArrayInitializer(
ArrayInitializerExpression::from_pest(&mut pair.into_inner()).unwrap()
)
},
Expression::ArrayInitializer(ArrayInitializerExpression::from_pest(&mut pair.into_inner()).unwrap())
}
Rule::expression_circuit_inline => {
Expression::CircuitInline(
CircuitInlineExpression::from_pest(&mut pair.into_inner()).unwrap(),
)
},
Expression::CircuitInline(CircuitInlineExpression::from_pest(&mut pair.into_inner()).unwrap())
}
Rule::expression_conditional => {
Expression::Ternary(
TernaryExpression::from_pest(&mut pair.into_inner()).unwrap(),
)
},
Expression::Ternary(TernaryExpression::from_pest(&mut pair.into_inner()).unwrap())
}
Rule::expression_not => {
let span = next.as_span();
let mut inner = next.into_inner();
let operation = match inner.next().unwrap().as_rule() {
Rule::operation_not => NotOperation::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap(),
rule => unreachable!("`expression_not` should yield `operation_pre_not`, found {:#?}", rule)
Rule::operation_not => {
NotOperation::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap()
}
rule => unreachable!("`expression_not` should yield `operation_pre_not`, found {:#?}", rule),
};
let expression = parse_term(inner.next().unwrap());
Expression::Not(NotExpression { operation, expression, span })
},
Expression::Not(NotExpression {
operation,
expression,
span,
})
}
Rule::expression_postfix => {
Expression::Postfix(
PostfixExpression::from_pest(&mut pair.into_inner()).unwrap(),
)
Expression::Postfix(PostfixExpression::from_pest(&mut pair.into_inner()).unwrap())
}
Rule::expression_primitive => {
let next = next.into_inner().next().unwrap();
match next.as_rule() {
Rule::value => {
Expression::Value(
Value::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap()
)
},
Rule::value => Expression::Value(
Value::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap(),
),
Rule::identifier => Expression::Identifier(
Identifier::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap(),
),
rule => unreachable!("`expression_primitive` should contain one of [`value`, `identifier`], found {:#?}", rule)
rule => unreachable!(
"`expression_primitive` should contain one of [`value`, `identifier`], found {:#?}",
rule
),
}
},
rule => unreachable!("`term` should contain one of ['value', 'identifier', 'expression', 'expression_not', 'expression_increment', 'expression_decrement'], found {:#?}", rule)
}
rule => unreachable!(
"`term` should contain one of ['value', 'identifier', 'expression', 'expression_not', 'expression_increment', 'expression_decrement'], found {:#?}",
rule
),
}
}
rule => unreachable!(
@ -155,8 +150,8 @@ fn binary_expression<'ast>(
}
impl<'ast> FromPest<'ast> for Expression<'ast> {
type Rule = Rule;
type FatalError = Void;
type Rule = Rule;
fn from_pest(pest: &mut Pairs<'ast, Rule>) -> Result<Self, ConversionError<Void>> {
let mut clone = pest.clone();

View File

@ -1,4 +1,7 @@
use crate::{ast::Rule, circuits::{CircuitFunction, CircuitFieldDefinition}};
use crate::{
ast::Rule,
circuits::{CircuitFieldDefinition, CircuitFunction},
};
use pest_ast::FromPest;

View File

@ -17,16 +17,8 @@ impl<'ast> fmt::Display for RangeOrExpression<'ast> {
RangeOrExpression::Range(ref range) => write!(
f,
"{}..{}",
range
.from
.as_ref()
.map(|e| e.0.to_string())
.unwrap_or("".to_string()),
range
.to
.as_ref()
.map(|e| e.0.to_string())
.unwrap_or("".to_string())
range.from.as_ref().map(|e| e.0.to_string()).unwrap_or("".to_string()),
range.to.as_ref().map(|e| e.0.to_string()).unwrap_or("".to_string())
),
}
}

View File

@ -1,4 +1,8 @@
use crate::{ast::Rule, common::{Identifier, Mutable}, types::Type};
use crate::{
ast::Rule,
common::{Identifier, Mutable},
types::Type,
};
use pest::Span;
use pest_ast::FromPest;

View File

@ -1,4 +1,4 @@
use crate::{ast::Rule, circuits::CircuitField, common::Identifier,};
use crate::{ast::Rule, circuits::CircuitField, common::Identifier};
use pest::Span;
use pest_ast::FromPest;

View File

@ -1,4 +1,4 @@
use crate::{common::Identifier, expressions::*, operations::BinaryOperation, values::Value,};
use crate::{common::Identifier, expressions::*, operations::BinaryOperation, values::Value};
use pest::Span;
use std::fmt;
@ -66,9 +66,7 @@ impl<'ast> fmt::Display for Expression<'ast> {
Expression::Value(ref expression) => write!(f, "{}", expression),
Expression::Identifier(ref expression) => write!(f, "{}", expression),
Expression::Not(ref expression) => write!(f, "!{}", expression.expression),
Expression::Binary(ref expression) => {
write!(f, "{} == {}", expression.left, expression.right)
}
Expression::Binary(ref expression) => write!(f, "{} == {}", expression.left, expression.right),
Expression::Ternary(ref expression) => write!(
f,
"if {} ? {} : {}",
@ -86,14 +84,10 @@ impl<'ast> fmt::Display for Expression<'ast> {
Expression::ArrayInitializer(ref expression) => {
write!(f, "[{} ; {}]", expression.expression, expression.count)
}
Expression::CircuitInline(ref expression) => write!(
f,
"inline circuit display not impl {}",
expression.identifier
),
Expression::Postfix(ref expression) => {
write!(f, "Postfix display not impl {}", expression.identifier)
Expression::CircuitInline(ref expression) => {
write!(f, "inline circuit display not impl {}", expression.identifier)
}
Expression::Postfix(ref expression) => write!(f, "Postfix display not impl {}", expression.identifier),
}
}
}

View File

@ -1,4 +1,10 @@
use crate::{ast::Rule, common::EOI, functions::{Function, TestFunction}, imports::Import, circuits::Circuit};
use crate::{
ast::Rule,
circuits::Circuit,
common::EOI,
functions::{Function, TestFunction},
imports::Import,
};
use pest::Span;
use pest_ast::FromPest;

View File

@ -1,4 +1,8 @@
use crate::{ast::Rule, common::{Identifier, Visibility, Mutable}, types::Type};
use crate::{
ast::Rule,
common::{Identifier, Mutable, Visibility},
types::Type,
};
use pest::Span;
use pest_ast::FromPest;

View File

@ -1,4 +1,8 @@
use crate::{ast::Rule, common::LineEnd, imports::{ImportSource, ImportSymbol}};
use crate::{
ast::Rule,
common::LineEnd,
imports::{ImportSource, ImportSymbol},
};
use pest::Span;
use pest_ast::FromPest;

View File

@ -1,4 +1,4 @@
use crate::ast::{Rule, span_into_string};
use crate::ast::{span_into_string, Rule};
use pest::Span;
use pest_ast::FromPest;

View File

@ -18,11 +18,11 @@ pub mod functions;
pub mod imports;
pub mod operations;
pub mod statements;
pub mod values;
pub mod types;
pub mod values;
use from_pest::FromPest;
use std::{path::PathBuf, fs};
use std::{fs, path::PathBuf};
pub struct LeoParser;
@ -35,9 +35,8 @@ impl LeoParser {
/// Parses the input file and constructs a syntax tree.
pub fn parse_file<'a>(file_path: &'a PathBuf, input_file: &'a str) -> Result<files::File<'a>, ParserError> {
// Parse the file using leo.pest
let mut file = ast::parse(input_file).map_err(|error| {
ParserError::from(error.with_path(file_path.to_str().unwrap()))
})?;
let mut file =
ast::parse(input_file).map_err(|error| ParserError::from(error.with_path(file_path.to_str().unwrap())))?;
// Build the abstract syntax tree
let syntax_tree = files::File::from_pest(&mut file).map_err(|_| ParserError::SyntaxTreeError)?;

View File

@ -13,9 +13,7 @@ pub enum AssertStatement<'ast> {
impl<'ast> fmt::Display for AssertStatement<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
AssertStatement::AssertEq(ref assert) => {
write!(f, "assert_eq({}, {});", assert.left, assert.right)
}
AssertStatement::AssertEq(ref assert) => write!(f, "assert_eq({}, {});", assert.left, assert.right),
}
}
}

View File

@ -1,4 +1,9 @@
use crate::{ast::Rule, common::{Assignee, LineEnd}, expressions::Expression, operations::AssignOperation};
use crate::{
ast::Rule,
common::{Assignee, LineEnd},
expressions::Expression,
operations::AssignOperation,
};
use pest::Span;
use pest_ast::FromPest;

View File

@ -1,4 +1,7 @@
use crate::{ast::Rule, statements::{ConditionalStatement, Statement}};
use crate::{
ast::Rule,
statements::{ConditionalStatement, Statement},
};
use pest_ast::FromPest;
use std::fmt;
@ -14,9 +17,7 @@ impl<'ast> fmt::Display for ConditionalNestedOrEndStatement<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
ConditionalNestedOrEndStatement::Nested(ref nested) => write!(f, "else {}", nested),
ConditionalNestedOrEndStatement::End(ref statements) => {
write!(f, "else {{\n \t{:#?}\n }}", statements)
}
ConditionalNestedOrEndStatement::End(ref statements) => write!(f, "else {{\n \t{:#?}\n }}", statements),
}
}
}

View File

@ -1,4 +1,8 @@
use crate::{ast::Rule, expressions::Expression, statements::{ConditionalNestedOrEndStatement, Statement}};
use crate::{
ast::Rule,
expressions::Expression,
statements::{ConditionalNestedOrEndStatement, Statement},
};
use pest::Span;
use pest_ast::FromPest;

View File

@ -1,4 +1,8 @@
use crate::{ast::Rule, common::{LineEnd, Variable}, expressions::Expression};
use crate::{
ast::Rule,
common::{LineEnd, Variable},
expressions::Expression,
};
use pest::Span;
use pest_ast::FromPest;

View File

@ -1,4 +1,4 @@
use crate::{ast::Rule, expressions::{Expression}, statements::Statement, common::Identifier};
use crate::{ast::Rule, common::Identifier, expressions::Expression, statements::Statement};
use pest::Span;
use pest_ast::FromPest;

View File

@ -1,4 +1,8 @@
use crate::{ast::Rule, common::{Identifier, LineEnd, Variable}, expressions::{Expression}};
use crate::{
ast::Rule,
common::{Identifier, LineEnd, Variable},
expressions::Expression,
};
use pest::Span;
use pest_ast::FromPest;

View File

@ -9,4 +9,4 @@ pub struct CircuitType<'ast> {
pub identifier: Identifier<'ast>,
#[pest_ast(outer())]
pub span: Span<'ast>,
}
}

View File

@ -1,4 +1,7 @@
use crate::{ast::Rule, types::{IntegerType, FieldType, GroupType, BooleanType}};
use crate::{
ast::Rule,
types::{BooleanType, FieldType, GroupType, IntegerType},
};
use pest_ast::FromPest;
@ -9,4 +12,4 @@ pub enum DataType {
Field(FieldType),
Group(GroupType),
Boolean(BooleanType),
}
}

View File

@ -4,4 +4,4 @@ use pest_ast::FromPest;
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::type_field))]
pub struct FieldType {}
pub struct FieldType {}

View File

@ -1,4 +1,4 @@
use crate::ast::{Rule, span_into_string};
use crate::ast::{span_into_string, Rule};
use pest::Span;
use pest_ast::FromPest;

View File

@ -1,4 +1,4 @@
use crate::{ast::Rule, types::FieldType, values::NumberValue,};
use crate::{ast::Rule, types::FieldType, values::NumberValue};
use pest::Span;
use pest_ast::FromPest;

View File

@ -1,4 +1,4 @@
use crate::{ast::Rule, types::GroupType, values::NumberValue,};
use crate::{ast::Rule, types::GroupType, values::NumberValue};
use pest::Span;
use pest_ast::FromPest;

View File

@ -1,4 +1,4 @@
use crate::ast::{Rule, span_into_string};
use crate::ast::{span_into_string, Rule};
use pest::Span;
use pest_ast::FromPest;
@ -17,4 +17,4 @@ impl<'ast> fmt::Display for NumberValue<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.value)
}
}
}

View File

@ -1,4 +1,7 @@
use crate::{ast::Rule, values::{BooleanValue, IntegerValue, FieldValue, GroupValue, NumberImplicitValue}};
use crate::{
ast::Rule,
values::{BooleanValue, FieldValue, GroupValue, IntegerValue, NumberImplicitValue},
};
use pest::Span;
use pest_ast::FromPest;

View File

@ -8,15 +8,16 @@ edition = "2018"
leo-ast = { path = "../ast", version = "0.1.0" }
leo-types = { path = "../types", version = "0.1.0" }
snarkos-algorithms = { path = "../../snarkOS/algorithms", version = "0.8.0" }
snarkos-curves = { path = "../../snarkOS/curves", version = "0.8.0" }
snarkos-errors = { path = "../../snarkOS/errors", version = "0.8.0" }
snarkos-gadgets = { path = "../../snarkOS/gadgets", version = "0.8.0" }
snarkos-models = { path = "../../snarkOS/models", version = "0.8.0" }
snarkos-utilities = { path = "../../snarkOS/utilities", version = "0.8.0" }
hex = { version = "0.4.2" }
log = { version = "0.4" }
rand = { version = "0.7" }
sha2 = { version = "0.8" }
thiserror = { version = "1.0" }
[dev-dependencies]
snarkos-utilities = { path = "../../snarkOS/utilities", version = "0.8.0" }

View File

@ -28,6 +28,17 @@ pub struct Compiler<F: Field + PrimeField, G: GroupType<F>> {
}
impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
pub fn new() -> Self {
Self {
package_name: "".to_string(),
main_file_path: PathBuf::new(),
program: Program::new(),
program_inputs: vec![],
output: None,
_engine: PhantomData,
}
}
pub fn init(package_name: String, main_file_path: PathBuf) -> Result<Self, CompilerError> {
let mut program = Self {
package_name,
@ -39,7 +50,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
};
// Generate the abstract syntax tree and assemble the program
program.parse_program()?;
let program_string = program.load_program()?;
program.parse_program(&program_string)?;
Ok(program)
}
@ -68,18 +80,19 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
generate_constraints(cs, self.program, self.program_inputs)
}
pub fn compile_test_constraints(
self,
cs: &mut TestConstraintSystem<F>,
) -> Result<(), CompilerError> {
pub fn compile_test_constraints(self, cs: &mut TestConstraintSystem<F>) -> Result<(), CompilerError> {
generate_test_constraints::<F, G>(cs, self.program)
}
fn parse_program(&mut self) -> Result<(), CompilerError> {
// Build the program syntax tree
fn load_program(&mut self) -> Result<String, CompilerError> {
// Load the program syntax tree from the file path
let file_path = &self.main_file_path;
let input_file = &LeoParser::load_file(file_path)?;
let syntax_tree = LeoParser::parse_file(file_path, input_file)?;
Ok(LeoParser::load_file(file_path)?)
}
pub fn parse_program(&mut self, program_string: &str) -> Result<(), CompilerError> {
// Parse the program syntax tree
let syntax_tree = LeoParser::parse_file(&self.main_file_path, program_string)?;
// Build program from syntax tree
let package_name = self.package_name.clone();
@ -94,12 +107,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
}
impl<F: Field + PrimeField, G: GroupType<F>> ConstraintSynthesizer<F> for Compiler<F, G> {
fn generate_constraints<CS: ConstraintSystem<F>>(
self,
cs: &mut CS,
) -> Result<(), SynthesisError> {
let _result =
generate_constraints::<_, G, _>(cs, self.program, self.program_inputs).unwrap();
fn generate_constraints<CS: ConstraintSystem<F>>(self, cs: &mut CS) -> Result<(), SynthesisError> {
let _result = generate_constraints::<_, G, _>(cs, self.program, self.program_inputs).unwrap();
// Write results to file or something

View File

@ -38,13 +38,9 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
// Check visibility of input
let number = if private {
Boolean::alloc(cs.ns(|| name), || {
bool_value.ok_or(SynthesisError::AssignmentMissing)
})?
Boolean::alloc(cs.ns(|| name), || bool_value.ok_or(SynthesisError::AssignmentMissing))?
} else {
Boolean::alloc_input(cs.ns(|| name), || {
bool_value.ok_or(SynthesisError::AssignmentMissing)
})?
Boolean::alloc_input(cs.ns(|| name), || bool_value.ok_or(SynthesisError::AssignmentMissing))?
};
Ok(ConstrainedValue::Boolean(number))
@ -54,9 +50,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
ConstrainedValue::Boolean(bool)
}
pub(crate) fn evaluate_not(
value: ConstrainedValue<F, G>,
) -> Result<ConstrainedValue<F, G>, BooleanError> {
pub(crate) fn evaluate_not(value: ConstrainedValue<F, G>) -> Result<ConstrainedValue<F, G>, BooleanError> {
match value {
ConstrainedValue::Boolean(boolean) => Ok(ConstrainedValue::Boolean(boolean.not())),
value => Err(BooleanError::CannotEvaluate(format!("!{}", value))),
@ -70,9 +64,9 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
right: ConstrainedValue<F, G>,
) -> Result<ConstrainedValue<F, G>, BooleanError> {
match (left, right) {
(ConstrainedValue::Boolean(left_bool), ConstrainedValue::Boolean(right_bool)) => Ok(
ConstrainedValue::Boolean(Boolean::or(cs, &left_bool, &right_bool)?),
),
(ConstrainedValue::Boolean(left_bool), ConstrainedValue::Boolean(right_bool)) => {
Ok(ConstrainedValue::Boolean(Boolean::or(cs, &left_bool, &right_bool)?))
}
(left_value, right_value) => Err(BooleanError::CannotEnforce(format!(
"{} || {}",
left_value, right_value
@ -87,9 +81,9 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
right: ConstrainedValue<F, G>,
) -> Result<ConstrainedValue<F, G>, BooleanError> {
match (left, right) {
(ConstrainedValue::Boolean(left_bool), ConstrainedValue::Boolean(right_bool)) => Ok(
ConstrainedValue::Boolean(Boolean::and(cs, &left_bool, &right_bool)?),
),
(ConstrainedValue::Boolean(left_bool), ConstrainedValue::Boolean(right_bool)) => {
Ok(ConstrainedValue::Boolean(Boolean::and(cs, &left_bool, &right_bool)?))
}
(left_value, right_value) => Err(BooleanError::CannotEnforce(format!(
"{} && {}",
left_value, right_value

View File

@ -4,10 +4,20 @@ use crate::{
constraints::{ConstrainedCircuitMember, ConstrainedProgram, ConstrainedValue},
errors::ExpressionError,
new_scope,
FieldType, GroupType,
FieldType,
GroupType,
};
use leo_types::{
CircuitFieldDefinition,
CircuitMember,
Expression,
Identifier,
Integer,
IntegerType,
RangeOrExpression,
SpreadOrExpression,
Type,
};
use leo_types::{CircuitFieldDefinition,CircuitMember, Expression, RangeOrExpression,
SpreadOrExpression, Identifier, Integer, IntegerType, Type};
use snarkos_models::{
curves::{Field, PrimeField},
@ -37,9 +47,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
// Check global scope (function and circuit names)
value.clone()
} else {
return Err(ExpressionError::UndefinedIdentifier(
unresolved_identifier.to_string(),
));
return Err(ExpressionError::UndefinedIdentifier(unresolved_identifier.to_string()));
};
result_value.resolve_type(expected_types)?;
@ -72,10 +80,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
let val_2 = ConstrainedValue::from_other(string, &val_1)?;
self.enforce_add_expression(cs, val_1, val_2)
}
(val_1, val_2) => Err(ExpressionError::IncompatibleTypes(format!(
"{} + {}",
val_1, val_2,
))),
(val_1, val_2) => Err(ExpressionError::IncompatibleTypes(format!("{} + {}", val_1, val_2,))),
}
}
@ -103,10 +108,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
let val_2 = ConstrainedValue::from_other(string, &val_1)?;
self.enforce_sub_expression(cs, val_1, val_2)
}
(val_1, val_2) => Err(ExpressionError::IncompatibleTypes(format!(
"{} - {}",
val_1, val_2,
))),
(val_1, val_2) => Err(ExpressionError::IncompatibleTypes(format!("{} - {}", val_1, val_2,))),
}
}
@ -131,12 +133,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
let val_2 = ConstrainedValue::from_other(string, &val_1)?;
self.enforce_mul_expression(cs, val_1, val_2)
}
(val_1, val_2) => {
return Err(ExpressionError::IncompatibleTypes(format!(
"{} * {}",
val_1, val_2,
)))
}
(val_1, val_2) => return Err(ExpressionError::IncompatibleTypes(format!("{} * {}", val_1, val_2,))),
}
}
@ -161,14 +158,10 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
let val_2 = ConstrainedValue::from_other(string, &val_1)?;
self.enforce_div_expression(cs, val_1, val_2)
}
(val_1, val_2) => {
return Err(ExpressionError::IncompatibleTypes(format!(
"{} / {}",
val_1, val_2,
)))
}
(val_1, val_2) => return Err(ExpressionError::IncompatibleTypes(format!("{} / {}", val_1, val_2,))),
}
}
fn enforce_pow_expression(
&mut self,
cs: &mut CS,
@ -187,10 +180,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
let val_2 = ConstrainedValue::from_other(string, &val_1)?;
self.enforce_pow_expression(cs, val_1, val_2)
}
(val_1, val_2) => Err(ExpressionError::IncompatibleTypes(format!(
"{} * {}",
val_1, val_2,
))),
(val_1, val_2) => Err(ExpressionError::IncompatibleTypes(format!("{} * {}", val_1, val_2,))),
}
}
@ -204,9 +194,9 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
(ConstrainedValue::Boolean(bool_1), ConstrainedValue::Boolean(bool_2)) => {
Ok(Self::boolean_eq(bool_1, bool_2))
}
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => Ok(
ConstrainedValue::Boolean(Boolean::Constant(num_1.eq(&num_2))),
),
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
Ok(ConstrainedValue::Boolean(Boolean::Constant(num_1.eq(&num_2))))
}
(ConstrainedValue::Field(fe_1), ConstrainedValue::Field(fe_2)) => {
Ok(ConstrainedValue::Boolean(Boolean::Constant(fe_1.eq(&fe_2))))
}
@ -221,10 +211,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
let val_2 = ConstrainedValue::from_other(string, &val_1)?;
self.evaluate_eq_expression(val_1, val_2)
}
(val_1, val_2) => Err(ExpressionError::IncompatibleTypes(format!(
"{} == {}",
val_1, val_2,
))),
(val_1, val_2) => Err(ExpressionError::IncompatibleTypes(format!("{} == {}", val_1, val_2,))),
}
}
@ -366,15 +353,9 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
value => return Err(ExpressionError::IfElseConditional(value.to_string())),
};
let resolved_second = self.enforce_branch(
cs,
file_scope.clone(),
function_scope.clone(),
expected_types,
second,
)?;
let resolved_third =
self.enforce_branch(cs, file_scope, function_scope, expected_types, third)?;
let resolved_second =
self.enforce_branch(cs, file_scope.clone(), function_scope.clone(), expected_types, second)?;
let resolved_third = self.enforce_branch(cs, file_scope, function_scope, expected_types, third)?;
match (resolved_second, resolved_third) {
(ConstrainedValue::Boolean(bool_2), ConstrainedValue::Boolean(bool_3)) => {
@ -382,8 +363,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
Ok(ConstrainedValue::Boolean(result))
}
(ConstrainedValue::Integer(integer_2), ConstrainedValue::Integer(integer_3)) => {
let result =
Integer::conditionally_select(cs, &resolved_first, &integer_2, &integer_3)?;
let result = Integer::conditionally_select(cs, &resolved_first, &integer_2, &integer_3)?;
Ok(ConstrainedValue::Integer(result))
}
(ConstrainedValue::Field(fe_1), ConstrainedValue::Field(fe_2)) => {
@ -394,9 +374,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
let result = G::conditionally_select(cs, &resolved_first, &ge_1, &ge_2)?;
Ok(ConstrainedValue::Group(result))
}
(_, _) => {
unimplemented!("conditional select gadget not implemented between given types")
}
(_, _) => unimplemented!("conditional select gadget not implemented between given types"),
}
}
@ -473,13 +451,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
index: Expression,
) -> Result<usize, ExpressionError> {
let expected_types = vec![Type::IntegerType(IntegerType::U32)];
match self.enforce_branch(
cs,
file_scope.clone(),
function_scope.clone(),
&expected_types,
index,
)? {
match self.enforce_branch(cs, file_scope.clone(), function_scope.clone(), &expected_types, index)? {
ConstrainedValue::Integer(number) => Ok(number.to_usize()),
value => Err(ExpressionError::InvalidIndex(value.to_string())),
}
@ -494,13 +466,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
array: Box<Expression>,
index: RangeOrExpression,
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
let array = match self.enforce_branch(
cs,
file_scope.clone(),
function_scope.clone(),
expected_types,
*array,
)? {
let array = match self.enforce_branch(cs, file_scope.clone(), function_scope.clone(), expected_types, *array)? {
ConstrainedValue::Array(array) => array,
value => return Err(ExpressionError::InvalidArrayAccess(value.to_string())),
};
@ -515,9 +481,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
Some(to_index) => to_index.to_usize(),
None => array.len(), // Array slice ends at array length
};
Ok(ConstrainedValue::Array(
array[from_resolved..to_resolved].to_owned(),
))
Ok(ConstrainedValue::Array(array[from_resolved..to_resolved].to_owned()))
}
RangeOrExpression::Expression(index) => {
let index_resolved = self.enforce_index(cs, file_scope, function_scope, index)?;
@ -540,9 +504,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
program_identifier = file_scope.clone();
}
if let Some(ConstrainedValue::CircuitDefinition(circuit_definition)) =
self.get_mut(&program_identifier)
{
if let Some(ConstrainedValue::CircuitDefinition(circuit_definition)) = self.get_mut(&program_identifier) {
let circuit_identifier = circuit_definition.identifier.clone();
let mut resolved_members = vec![];
for member in circuit_definition.members.clone().into_iter() {
@ -563,14 +525,9 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
field.expression,
)?;
resolved_members
.push(ConstrainedCircuitMember(identifier, field_value))
}
None => {
return Err(ExpressionError::ExpectedCircuitMember(
identifier.to_string(),
))
resolved_members.push(ConstrainedCircuitMember(identifier, field_value))
}
None => return Err(ExpressionError::ExpectedCircuitMember(identifier.to_string())),
}
}
CircuitMember::CircuitFunction(_static, function) => {
@ -579,14 +536,10 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
ConstrainedValue::Function(Some(circuit_identifier.clone()), function);
if _static {
constrained_function_value =
ConstrainedValue::Static(Box::new(constrained_function_value));
constrained_function_value = ConstrainedValue::Static(Box::new(constrained_function_value));
}
resolved_members.push(ConstrainedCircuitMember(
identifier,
constrained_function_value,
));
resolved_members.push(ConstrainedCircuitMember(identifier, constrained_function_value));
}
};
}
@ -620,10 +573,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
value => return Err(ExpressionError::InvalidCircuitAccess(value.to_string())),
};
let matched_member = members
.clone()
.into_iter()
.find(|member| member.0 == circuit_member);
let matched_member = members.clone().into_iter().find(|member| member.0 == circuit_member);
match matched_member {
Some(member) => {
@ -635,12 +585,9 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
ConstrainedValue::Function(_, _) => {}
ConstrainedValue::Static(_) => {}
_ => {
let circuit_scope =
new_scope(file_scope.clone(), circuit_name.to_string());
let function_scope =
new_scope(circuit_scope, member.0.to_string());
let field =
new_scope(function_scope, stored_member.0.to_string());
let circuit_scope = new_scope(file_scope.clone(), circuit_name.to_string());
let function_scope = new_scope(circuit_scope, member.0.to_string());
let field = new_scope(function_scope, stored_member.0.to_string());
self.store(field, stored_member.1.clone());
}
@ -648,7 +595,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
}
}
ConstrainedValue::Static(value) => {
return Err(ExpressionError::InvalidStaticAccess(value.to_string()))
return Err(ExpressionError::InvalidStaticAccess(value.to_string()));
}
_ => {}
}
@ -684,9 +631,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
// Find static circuit function
let matched_function = circuit.members.into_iter().find(|member| match member {
CircuitMember::CircuitFunction(_static, function) => {
function.function_name == circuit_member
}
CircuitMember::CircuitFunction(_static, function) => function.function_name == circuit_member,
_ => false,
});
@ -696,23 +641,18 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
if _static {
function
} else {
return Err(ExpressionError::InvalidMemberAccess(
function.function_name.to_string(),
));
return Err(ExpressionError::InvalidMemberAccess(function.function_name.to_string()));
}
}
_ => {
return Err(ExpressionError::UndefinedStaticAccess(
circuit.identifier.to_string(),
circuit_member.to_string(),
))
));
}
};
Ok(ConstrainedValue::Function(
Some(circuit.identifier),
function,
))
Ok(ConstrainedValue::Function(Some(circuit.identifier), function))
}
fn enforce_function_call_expression(
@ -780,8 +720,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
expected_types: &Vec<Type>,
expression: Expression,
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
let mut branch =
self.enforce_expression(cs, file_scope, function_scope, expected_types, expression)?;
let mut branch = self.enforce_expression(cs, file_scope, function_scope, expected_types, expression)?;
branch.get_inner_mut();
branch.resolve_type(expected_types)?;
@ -798,20 +737,10 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
left: Expression,
right: Expression,
) -> Result<(ConstrainedValue<F, G>, ConstrainedValue<F, G>), ExpressionError> {
let resolved_left = self.enforce_branch(
cs,
file_scope.clone(),
function_scope.clone(),
expected_types,
left,
)?;
let resolved_right = self.enforce_branch(
cs,
file_scope.clone(),
function_scope.clone(),
expected_types,
right,
)?;
let resolved_left =
self.enforce_branch(cs, file_scope.clone(), function_scope.clone(), expected_types, left)?;
let resolved_right =
self.enforce_branch(cs, file_scope.clone(), function_scope.clone(), expected_types, right)?;
Ok((resolved_left, resolved_right))
}
@ -826,19 +755,14 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
match expression {
// Variables
Expression::Identifier(unresolved_variable) => self.evaluate_identifier(
file_scope,
function_scope,
expected_types,
unresolved_variable,
),
Expression::Identifier(unresolved_variable) => {
self.evaluate_identifier(file_scope, function_scope, expected_types, unresolved_variable)
}
// Values
Expression::Integer(integer) => Ok(ConstrainedValue::Integer(integer)),
Expression::Field(field) => Ok(ConstrainedValue::Field(FieldType::constant(field)?)),
Expression::Group(group_affine) => {
Ok(ConstrainedValue::Group(G::constant(group_affine)?))
}
Expression::Group(group_affine) => Ok(ConstrainedValue::Group(G::constant(group_affine)?)),
Expression::Boolean(bool) => Ok(Self::get_boolean_constant(bool)),
Expression::Implicit(value) => Self::enforce_number_implicit(expected_types, value),
@ -1012,23 +936,14 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
Expression::Array(array) => {
self.enforce_array_expression(cs, file_scope, function_scope, expected_types, array)
}
Expression::ArrayAccess(array, index) => self.enforce_array_access_expression(
cs,
file_scope,
function_scope,
expected_types,
array,
*index,
),
Expression::ArrayAccess(array, index) => {
self.enforce_array_access_expression(cs, file_scope, function_scope, expected_types, array, *index)
}
// Circuits
Expression::Circuit(circuit_name, members) => self.enforce_circuit_expression(
cs,
file_scope,
function_scope,
circuit_name,
members,
),
Expression::Circuit(circuit_name, members) => {
self.enforce_circuit_expression(cs, file_scope, function_scope, circuit_name, members)
}
Expression::CircuitMemberAccess(circuit_variable, circuit_member) => self
.enforce_circuit_access_expression(
cs,

View File

@ -1,8 +1,6 @@
//! Methods to enforce constraints on field elements in a resolved Leo program.
use crate::{
constraints::ConstrainedValue, errors::FieldError, FieldType, GroupType,
};
use crate::{constraints::ConstrainedValue, errors::FieldError, FieldType, GroupType};
use leo_types::InputValue;
use snarkos_errors::gadgets::SynthesisError;
@ -31,13 +29,9 @@ pub(crate) fn field_from_input<F: Field + PrimeField, G: GroupType<F>, CS: Const
// Check visibility of parameter
let field_value = if private {
FieldType::alloc(cs.ns(|| name), || {
field_option.ok_or(SynthesisError::AssignmentMissing)
})?
FieldType::alloc(cs.ns(|| name), || field_option.ok_or(SynthesisError::AssignmentMissing))?
} else {
FieldType::alloc_input(cs.ns(|| name), || {
field_option.ok_or(SynthesisError::AssignmentMissing)
})?
FieldType::alloc_input(cs.ns(|| name), || field_option.ok_or(SynthesisError::AssignmentMissing))?
};
Ok(ConstrainedValue::Field(field_value))

View File

@ -4,8 +4,10 @@
use crate::{
constraints::{new_scope, ConstrainedProgram, ConstrainedValue},
errors::{FunctionError, ImportError},
field_from_input, group_from_input,
GroupType};
field_from_input,
group_from_input,
GroupType,
};
use leo_types::{Expression, Function, Identifier, InputValue, Integer, Program, Type};
use snarkos_models::{
@ -35,19 +37,10 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
// Evaluate the function input value as pass by value from the caller or
// evaluate as an expression in the current function scope
match input {
Expression::Identifier(identifier) => Ok(self.evaluate_identifier(
caller_scope,
function_name,
&expected_types,
identifier,
)?),
expression => Ok(self.enforce_expression(
cs,
scope,
function_name,
&expected_types,
expression,
)?),
Expression::Identifier(identifier) => {
Ok(self.evaluate_identifier(caller_scope, function_name, &expected_types, identifier)?)
}
expression => Ok(self.enforce_expression(cs, scope, function_name, &expected_types, expression)?),
}
}
@ -65,9 +58,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
Self::check_arguments_length(function.inputs.len(), inputs.len())?;
// Store input values as new variables in resolved program
for (input_model, input_expression) in
function.inputs.clone().iter().zip(inputs.into_iter())
{
for (input_model, input_expression) in function.inputs.clone().iter().zip(inputs.into_iter()) {
// First evaluate input expression
let mut input_value = self.enforce_input(
cs,
@ -83,8 +74,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
}
// Store input as variable with {function_name}_{input_name}
let input_program_identifier =
new_scope(function_name.clone(), input_model.identifier.name.clone());
let input_program_identifier = new_scope(function_name.clone(), input_model.identifier.name.clone());
self.store(input_program_identifier, input_value);
}
@ -149,18 +139,10 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
let value_name = new_scope(name.clone(), i.to_string());
let value_type = array_type.outer_dimension(&array_dimensions);
array_value.push(
self.allocate_main_function_input(
cs, value_type, value_name, private, None,
)?,
);
array_value.push(self.allocate_main_function_input(cs, value_type, value_name, private, None)?);
}
}
_ => {
return Err(FunctionError::InvalidArray(
input_value.unwrap().to_string(),
))
}
_ => return Err(FunctionError::InvalidArray(input_value.unwrap().to_string())),
}
Ok(ConstrainedValue::Array(array_value))
@ -185,9 +167,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
Type::Field => Ok(field_from_input(cs, name, private, input_value)?),
Type::Group => Ok(group_from_input(cs, name, private, input_value)?),
Type::Boolean => Ok(self.bool_from_input(cs, name, private, input_value)?),
Type::Array(_type, dimensions) => {
self.allocate_array(cs, name, private, *_type, dimensions, input_value)
}
Type::Array(_type, dimensions) => self.allocate_array(cs, name, private, *_type, dimensions, input_value),
_ => unimplemented!("main function input not implemented for type"),
}
}
@ -206,9 +186,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
// Iterate over main function inputs and allocate new passed-by variable values
let mut input_variables = vec![];
for (input_model, input_option) in
function.inputs.clone().into_iter().zip(inputs.into_iter())
{
for (input_model, input_option) in function.inputs.clone().into_iter().zip(inputs.into_iter()) {
let input_name = new_scope(function_name.clone(), input_model.identifier.name.clone());
let input_value = self.allocate_main_function_input(
cs,
@ -229,11 +207,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
self.enforce_function(cs, scope, function_name, function, input_variables)
}
pub(crate) fn resolve_definitions(
&mut self,
cs: &mut CS,
program: Program,
) -> Result<(), ImportError> {
pub(crate) fn resolve_definitions(&mut self, cs: &mut CS, program: Program) -> Result<(), ImportError> {
let program_name = program.name.clone();
// evaluate and store all imports
@ -244,30 +218,16 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
.collect::<Result<Vec<_>, ImportError>>()?;
// evaluate and store all circuit definitions
program
.circuits
.into_iter()
.for_each(|(identifier, circuit)| {
let resolved_circuit_name =
new_scope(program_name.to_string(), identifier.to_string());
self.store(
resolved_circuit_name,
ConstrainedValue::CircuitDefinition(circuit),
);
});
program.circuits.into_iter().for_each(|(identifier, circuit)| {
let resolved_circuit_name = new_scope(program_name.to_string(), identifier.to_string());
self.store(resolved_circuit_name, ConstrainedValue::CircuitDefinition(circuit));
});
// evaluate and store all function definitions
program
.functions
.into_iter()
.for_each(|(function_name, function)| {
let resolved_function_name =
new_scope(program_name.to_string(), function_name.to_string());
self.store(
resolved_function_name,
ConstrainedValue::Function(None, function),
);
});
program.functions.into_iter().for_each(|(function_name, function)| {
let resolved_function_name = new_scope(program_name.to_string(), function_name.to_string());
self.store(resolved_function_name, ConstrainedValue::Function(None, function));
});
Ok(())
}

View File

@ -27,13 +27,9 @@ pub(crate) fn group_from_input<F: Field + PrimeField, G: GroupType<F>, CS: Const
// Check visibility of parameter
let group_value = if private {
G::alloc(cs.ns(|| name), || {
group_option.ok_or(SynthesisError::AssignmentMissing)
})?
G::alloc(cs.ns(|| name), || group_option.ok_or(SynthesisError::AssignmentMissing))?
} else {
G::alloc_input(cs.ns(|| name), || {
group_option.ok_or(SynthesisError::AssignmentMissing)
})?
G::alloc_input(cs.ns(|| name), || group_option.ok_or(SynthesisError::AssignmentMissing))?
};
Ok(ConstrainedValue::Group(group_value))

View File

@ -14,12 +14,7 @@ use snarkos_models::{
use std::env::current_dir;
impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
pub fn enforce_import(
&mut self,
cs: &mut CS,
scope: String,
import: Import,
) -> Result<(), ImportError> {
pub fn enforce_import(&mut self, cs: &mut CS, scope: String, import: Import) -> Result<(), ImportError> {
let path = current_dir().map_err(|error| ImportError::DirectoryError(error))?;
// Sanitize the package path to the imports directory
@ -64,19 +59,17 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
.find(|(circuit_name, _circuit_def)| symbol.symbol == *circuit_name);
let value = match matched_circuit {
Some((_circuit_name, circuit_def)) => {
ConstrainedValue::CircuitDefinition(circuit_def)
}
Some((_circuit_name, circuit_def)) => ConstrainedValue::CircuitDefinition(circuit_def),
None => {
// see if the imported symbol is a function
let matched_function = program.functions.clone().into_iter().find(
|(function_name, _function)| symbol.symbol.name == *function_name.name,
);
let matched_function = program
.functions
.clone()
.into_iter()
.find(|(function_name, _function)| symbol.symbol.name == *function_name.name);
match matched_function {
Some((_function_name, function)) => {
ConstrainedValue::Function(None, function)
}
Some((_function_name, function)) => ConstrainedValue::Function(None, function),
None => unimplemented!(
"cannot find imported symbol {} in imported file {}",
symbol,
@ -88,8 +81,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
// take the alias if it is present
let resolved_name = symbol.alias.unwrap_or(symbol.symbol);
let resolved_circuit_name =
new_scope(program_name.to_string(), resolved_name.to_string());
let resolved_circuit_name = new_scope(program_name.to_string(), resolved_name.to_string());
// store imported circuit under resolved name
self.store(resolved_circuit_name, value);
@ -99,9 +91,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
program
.imports
.into_iter()
.map(|nested_import| {
self.enforce_import(cs, program_name.name.clone(), nested_import)
})
.map(|nested_import| self.enforce_import(cs, program_name.name.clone(), nested_import))
.collect::<Result<Vec<_>, ImportError>>()?;
Ok(())

View File

@ -27,10 +27,7 @@ pub use value::*;
pub mod statement;
pub use statement::*;
use crate::{
errors::CompilerError,
GroupType,
};
use crate::{errors::CompilerError, GroupType};
use leo_types::{InputValue, Program};
use snarkos_models::{
@ -55,8 +52,7 @@ pub fn generate_constraints<F: Field + PrimeField, G: GroupType<F>, CS: Constrai
match main.clone() {
ConstrainedValue::Function(_circuit_identifier, function) => {
let result =
resolved_program.enforce_main_function(cs, program_name, function, parameters)?;
let result = resolved_program.enforce_main_function(cs, program_name, function, parameters)?;
log::debug!("{}", result);
Ok(result)
}

View File

@ -6,7 +6,18 @@ use crate::{
new_scope,
GroupType,
};
use leo_types::{Assignee, ConditionalNestedOrEndStatement, ConditionalStatement, Statement, Expression, Identifier, Integer, RangeOrExpression, Type, Variable};
use leo_types::{
Assignee,
ConditionalNestedOrEndStatement,
ConditionalStatement,
Expression,
Identifier,
Integer,
RangeOrExpression,
Statement,
Type,
Variable,
};
use snarkos_models::{
curves::{Field, PrimeField},
@ -21,16 +32,11 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
match assignee {
Assignee::Identifier(name) => new_scope(scope, name.to_string()),
Assignee::Array(array, _index) => self.resolve_assignee(scope, *array),
Assignee::CircuitField(circuit_name, _member) => {
self.resolve_assignee(scope, *circuit_name)
}
Assignee::CircuitField(circuit_name, _member) => self.resolve_assignee(scope, *circuit_name),
}
}
fn get_mutable_assignee(
&mut self,
name: String,
) -> Result<&mut ConstrainedValue<F, G>, StatementError> {
fn get_mutable_assignee(&mut self, name: String) -> Result<&mut ConstrainedValue<F, G>, StatementError> {
// Check that assignee exists and is mutable
Ok(match self.get_mut(&name) {
Some(value) => match value {
@ -53,8 +59,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
// Resolve index so we know if we are assigning to a single value or a range of values
match range_or_expression {
RangeOrExpression::Expression(index) => {
let index =
self.enforce_index(cs, file_scope.clone(), function_scope.clone(), index)?;
let index = self.enforce_index(cs, file_scope.clone(), function_scope.clone(), index)?;
// Modify the single value of the array in place
match self.get_mutable_assignee(name)? {
@ -104,18 +109,14 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
ConstrainedValue::Function(_circuit_identifier, function) => {
return Err(StatementError::ImmutableCircuitFunction(
function.function_name.to_string(),
))
));
}
ConstrainedValue::Static(_value) => {
return Err(StatementError::ImmutableCircuitFunction("static".into()))
return Err(StatementError::ImmutableCircuitFunction("static".into()));
}
_ => object.1 = new_value.to_owned(),
},
None => {
return Err(StatementError::UndefinedCircuitObject(
object_name.to_string(),
))
}
None => return Err(StatementError::UndefinedCircuitObject(object_name.to_string())),
}
}
_ => return Err(StatementError::UndefinedCircuit(object_name.to_string())),
@ -136,13 +137,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
let variable_name = self.resolve_assignee(function_scope.clone(), assignee.clone());
// Evaluate new value
let new_value = self.enforce_expression(
cs,
file_scope.clone(),
function_scope.clone(),
&vec![],
expression,
)?;
let new_value = self.enforce_expression(cs, file_scope.clone(), function_scope.clone(), &vec![], expression)?;
// Mutate the old value into the new value
match assignee {
@ -232,10 +227,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
function,
)? {
ConstrainedValue::Return(values) => values,
value => unimplemented!(
"multiple assignment only implemented for functions, got {}",
value
),
value => unimplemented!("multiple assignment only implemented for functions, got {}", value),
};
if variables.len() != return_values.len() {
@ -332,30 +324,16 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
// use gadget impl
if condition.eq(&Boolean::Constant(true)) {
self.iterate_or_early_return(
cs,
file_scope,
function_scope,
statement.statements,
return_types,
)
self.iterate_or_early_return(cs, file_scope, function_scope, statement.statements, return_types)
} else {
match statement.next {
Some(next) => match next {
ConditionalNestedOrEndStatement::Nested(nested) => self.enforce_conditional_statement(
cs,
file_scope,
function_scope,
*nested,
return_types,
),
ConditionalNestedOrEndStatement::End(statements) => self.iterate_or_early_return(
cs,
file_scope,
function_scope,
statements,
return_types,
),
ConditionalNestedOrEndStatement::Nested(nested) => {
self.enforce_conditional_statement(cs, file_scope, function_scope, *nested, return_types)
}
ConditionalNestedOrEndStatement::End(statements) => {
self.iterate_or_early_return(cs, file_scope, function_scope, statements, return_types)
}
},
None => Ok(None),
}
@ -410,11 +388,9 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
(ConstrainedValue::Boolean(bool_1), ConstrainedValue::Boolean(bool_2)) => {
self.enforce_boolean_eq(cs, bool_1, bool_2)?
}
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
num_1.enforce_equal(cs, &num_2).map_err(|_| {
StatementError::AssertionFailed(num_1.to_string(), num_2.to_string())
})?
}
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => num_1
.enforce_equal(cs, &num_2)
.map_err(|_| StatementError::AssertionFailed(num_1.to_string(), num_2.to_string()))?,
(ConstrainedValue::Field(fe_1), ConstrainedValue::Field(fe_2)) => fe_1
.enforce_equal(cs, &fe_2)
.map_err(|_| StatementError::AssertionFailed(fe_1.to_string(), fe_2.to_string()))?,
@ -426,12 +402,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
self.enforce_assert_eq_statement(cs, left, right)?;
}
}
(val_1, val_2) => {
return Err(StatementError::AssertEq(
val_1.to_string(),
val_2.to_string(),
))
}
(val_1, val_2) => return Err(StatementError::AssertEq(val_1.to_string(), val_2.to_string())),
})
}
@ -446,49 +417,21 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
let mut res = None;
match statement {
Statement::Return(expressions) => {
res = Some(self.enforce_return_statement(
cs,
file_scope,
function_scope,
expressions,
return_types,
)?);
res = Some(self.enforce_return_statement(cs, file_scope, function_scope, expressions, return_types)?);
}
Statement::Definition(variable, expression) => {
self.enforce_definition_statement(
cs,
file_scope,
function_scope,
variable,
expression,
)?;
self.enforce_definition_statement(cs, file_scope, function_scope, variable, expression)?;
}
Statement::Assign(variable, expression) => {
self.enforce_assign_statement(
cs,
file_scope,
function_scope,
variable,
expression,
)?;
self.enforce_assign_statement(cs, file_scope, function_scope, variable, expression)?;
}
Statement::MultipleAssign(variables, function) => {
self.enforce_multiple_definition_statement(
cs,
file_scope,
function_scope,
variables,
function,
)?;
self.enforce_multiple_definition_statement(cs, file_scope, function_scope, variables, function)?;
}
Statement::Conditional(statement) => {
if let Some(early_return) = self.enforce_conditional_statement(
cs,
file_scope,
function_scope,
statement,
return_types,
)? {
if let Some(early_return) =
self.enforce_conditional_statement(cs, file_scope, function_scope, statement, return_types)?
{
res = Some(early_return)
}
}
@ -507,31 +450,15 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
}
}
Statement::AssertEq(left, right) => {
let resolved_left = self.enforce_expression(
cs,
file_scope.clone(),
function_scope.clone(),
&vec![],
left,
)?;
let resolved_right = self.enforce_expression(
cs,
file_scope.clone(),
function_scope.clone(),
&vec![],
right,
)?;
let resolved_left =
self.enforce_expression(cs, file_scope.clone(), function_scope.clone(), &vec![], left)?;
let resolved_right =
self.enforce_expression(cs, file_scope.clone(), function_scope.clone(), &vec![], right)?;
self.enforce_assert_eq_statement(cs, resolved_left, resolved_right)?;
}
Statement::Expression(expression) => {
match self.enforce_expression(
cs,
file_scope,
function_scope,
&vec![],
expression.clone(),
)? {
match self.enforce_expression(cs, file_scope, function_scope, &vec![], expression.clone())? {
ConstrainedValue::Return(values) => {
if !values.is_empty() {
return Err(StatementError::Unassigned(expression.to_string()));

View File

@ -1,9 +1,6 @@
//! The in memory stored value for a defined name in a resolved Leo program.
use crate::{
errors::ValueError,
FieldType, GroupType,
};
use crate::{errors::ValueError, FieldType, GroupType};
use leo_types::{Circuit, Function, Identifier, Integer, IntegerType, Type};
use snarkos_models::{
@ -16,10 +13,7 @@ use snarkos_models::{
use std::fmt;
#[derive(Clone, PartialEq, Eq)]
pub struct ConstrainedCircuitMember<F: Field + PrimeField, G: GroupType<F>>(
pub Identifier,
pub ConstrainedValue<F, G>,
);
pub struct ConstrainedCircuitMember<F: Field + PrimeField, G: GroupType<F>>(pub Identifier, pub ConstrainedValue<F, G>);
#[derive(Clone, PartialEq, Eq)]
pub enum ConstrainedValue<F: Field + PrimeField, G: GroupType<F>> {
@ -42,10 +36,7 @@ pub enum ConstrainedValue<F: Field + PrimeField, G: GroupType<F>> {
}
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
pub(crate) fn from_other(
value: String,
other: &ConstrainedValue<F, G>,
) -> Result<Self, ValueError> {
pub(crate) fn from_other(value: String, other: &ConstrainedValue<F, G>) -> Result<Self, ValueError> {
let other_type = other.to_type();
ConstrainedValue::from_type(value, &other_type)
@ -62,9 +53,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
})),
Type::Field => Ok(ConstrainedValue::Field(FieldType::constant(value)?)),
Type::Group => Ok(ConstrainedValue::Group(G::constant(value)?)),
Type::Boolean => Ok(ConstrainedValue::Boolean(Boolean::Constant(
value.parse::<bool>()?,
))),
Type::Boolean => Ok(ConstrainedValue::Boolean(Boolean::Constant(value.parse::<bool>()?))),
Type::Array(ref _type, _dimensions) => ConstrainedValue::from_type(value, _type),
_ => Ok(ConstrainedValue::Unresolved(value)),
}
@ -137,9 +126,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> fmt::Display for ConstrainedValue<F
ConstrainedValue::CircuitDefinition(ref _definition) => {
unimplemented!("cannot return circuit definition in program")
}
ConstrainedValue::Function(ref _circuit_option, ref function) => {
write!(f, "{}", function)
}
ConstrainedValue::Function(ref _circuit_option, ref function) => write!(f, "{}", function),
ConstrainedValue::Mutable(ref value) => write!(f, "mut {}", value),
ConstrainedValue::Static(ref value) => write!(f, "static {}", value),
ConstrainedValue::Unresolved(ref value) => write!(f, "unresolved {}", value),

View File

@ -1,5 +1,5 @@
use crate::errors::{FunctionError, ImportError};
use leo_ast::{SyntaxError, ParserError};
use leo_ast::{ParserError, SyntaxError};
use leo_types::IntegerError;
use std::{io, path::PathBuf};

View File

@ -1,6 +1,4 @@
use crate::errors::{
BooleanError, FieldError, FunctionError, GroupError, ValueError,
};
use crate::errors::{BooleanError, FieldError, FunctionError, GroupError, ValueError};
use leo_types::IntegerError;
use snarkos_errors::gadgets::SynthesisError;
@ -47,10 +45,7 @@ pub enum ExpressionError {
#[error("Spread should contain an array, got {}", _0)]
InvalidSpread(String),
#[error(
"Array {} must be declared before it is used in an inline expression",
_0
)]
#[error("Array {} must be declared before it is used in an inline expression", _0)]
UndefinedArray(String),
// Circuits
@ -66,10 +61,7 @@ pub enum ExpressionError {
#[error("Static member {} must be accessed using `::` syntax", _0)]
InvalidStaticAccess(String),
#[error(
"Circuit {} must be declared before it is used in an inline expression",
_0
)]
#[error("Circuit {} must be declared before it is used in an inline expression", _0)]
UndefinedCircuit(String),
#[error("Circuit {} has no member {}", _0, _1)]
@ -85,10 +77,7 @@ pub enum ExpressionError {
#[error("{}", _0)]
FunctionError(#[from] Box<FunctionError>),
#[error(
"Function {} must be declared before it is used in an inline expression",
_0
)]
#[error("Function {} must be declared before it is used in an inline expression", _0)]
UndefinedFunction(String),
// Conditionals

View File

@ -1,6 +1,4 @@
use crate::errors::{
BooleanError, ExpressionError, FieldError, GroupError, StatementError, ValueError,
};
use crate::errors::{BooleanError, ExpressionError, FieldError, GroupError, StatementError, ValueError};
use leo_types::IntegerError;
#[derive(Debug, Error)]

View File

@ -43,11 +43,7 @@ pub enum StatementError {
#[error("Cannot assign to immutable variable {}", _0)]
ImmutableAssign(String),
#[error(
"Multiple definition statement expected {} return values, got {}",
_0,
_1
)]
#[error("Multiple definition statement expected {} return values, got {}", _0, _1)]
InvalidNumberOfDefinitions(usize, usize),
#[error("Function return statement expected {} return values, got {}", _0, _1)]

View File

@ -3,11 +3,10 @@
use crate::errors::FieldError;
use snarkos_errors::gadgets::SynthesisError;
use snarkos_models::gadgets::curves::FieldGadget;
use snarkos_models::{
curves::{Field, PrimeField},
gadgets::{
curves::FpGadget,
curves::{FieldGadget, FpGadget},
r1cs::ConstraintSystem,
utilities::{
alloc::AllocGadget,
@ -15,12 +14,12 @@ use snarkos_models::{
eq::{ConditionalEqGadget, EqGadget},
select::CondSelectGadget,
uint::UInt8,
ToBitsGadget, ToBytesGadget,
ToBitsGadget,
ToBytesGadget,
},
},
};
use std::borrow::Borrow;
use std::cmp::Ordering;
use std::{borrow::Borrow, cmp::Ordering};
#[derive(Clone, Debug)]
pub enum FieldType<F: Field + PrimeField> {
@ -55,9 +54,9 @@ impl<F: Field + PrimeField> FieldType<F> {
}
(FieldType::Constant(constant_value), FieldType::Allocated(allocated_value))
| (FieldType::Allocated(allocated_value), FieldType::Constant(constant_value)) => Ok(
FieldType::Allocated(allocated_value.add_constant(cs, constant_value)?),
),
| (FieldType::Allocated(allocated_value), FieldType::Constant(constant_value)) => {
Ok(FieldType::Allocated(allocated_value.add_constant(cs, constant_value)?))
}
}
}
@ -74,9 +73,9 @@ impl<F: Field + PrimeField> FieldType<F> {
}
(FieldType::Constant(constant_value), FieldType::Allocated(allocated_value))
| (FieldType::Allocated(allocated_value), FieldType::Constant(constant_value)) => Ok(
FieldType::Allocated(allocated_value.sub_constant(cs, constant_value)?),
),
| (FieldType::Allocated(allocated_value), FieldType::Constant(constant_value)) => {
Ok(FieldType::Allocated(allocated_value.sub_constant(cs, constant_value)?))
}
}
}
@ -93,22 +92,16 @@ impl<F: Field + PrimeField> FieldType<F> {
}
(FieldType::Constant(constant_value), FieldType::Allocated(allocated_value))
| (FieldType::Allocated(allocated_value), FieldType::Constant(constant_value)) => Ok(
FieldType::Allocated(allocated_value.mul_by_constant(cs, constant_value)?),
),
| (FieldType::Allocated(allocated_value), FieldType::Constant(constant_value)) => Ok(FieldType::Allocated(
allocated_value.mul_by_constant(cs, constant_value)?,
)),
}
}
pub fn div<CS: ConstraintSystem<F>>(
&self,
mut cs: CS,
other: &Self,
) -> Result<Self, FieldError> {
pub fn div<CS: ConstraintSystem<F>>(&self, mut cs: CS, other: &Self) -> Result<Self, FieldError> {
let inverse = match other {
FieldType::Constant(constant) => {
let constant_inverse = constant
.inverse()
.ok_or(FieldError::NoInverse(constant.to_string()))?;
let constant_inverse = constant.inverse().ok_or(FieldError::NoInverse(constant.to_string()))?;
FieldType::Constant(constant_inverse)
}
FieldType::Allocated(allocated) => {
@ -134,25 +127,16 @@ impl<F: Field + PrimeField> FieldType<F> {
F::from_str(&field_string).map_err(|_| SynthesisError::AssignmentMissing)
}
pub fn allocated<CS: ConstraintSystem<F>>(
&self,
mut cs: CS,
) -> Result<FpGadget<F>, SynthesisError> {
pub fn allocated<CS: ConstraintSystem<F>>(&self, mut cs: CS) -> Result<FpGadget<F>, SynthesisError> {
match self {
FieldType::Constant(constant) => {
FpGadget::alloc(&mut cs.ns(|| format!("{:?}", constant)), || Ok(constant))
}
FieldType::Constant(constant) => FpGadget::alloc(&mut cs.ns(|| format!("{:?}", constant)), || Ok(constant)),
FieldType::Allocated(allocated) => Ok(allocated.clone()),
}
}
}
impl<F: Field + PrimeField> AllocGadget<String, F> for FieldType<F> {
fn alloc<
Fn: FnOnce() -> Result<T, SynthesisError>,
T: Borrow<String>,
CS: ConstraintSystem<F>,
>(
fn alloc<Fn: FnOnce() -> Result<T, SynthesisError>, T: Borrow<String>, CS: ConstraintSystem<F>>(
cs: CS,
value_gen: Fn,
) -> Result<Self, SynthesisError> {
@ -161,11 +145,7 @@ impl<F: Field + PrimeField> AllocGadget<String, F> for FieldType<F> {
Ok(FieldType::Allocated(value))
}
fn alloc_input<
Fn: FnOnce() -> Result<T, SynthesisError>,
T: Borrow<String>,
CS: ConstraintSystem<F>,
>(
fn alloc_input<Fn: FnOnce() -> Result<T, SynthesisError>, T: Borrow<String>, CS: ConstraintSystem<F>>(
cs: CS,
value_gen: Fn,
) -> Result<Self, SynthesisError> {
@ -239,11 +219,7 @@ impl<F: Field + PrimeField> CondSelectGadget<F> for FieldType<F> {
second: &Self,
) -> Result<Self, SynthesisError> {
if let Boolean::Constant(cond) = *cond {
if cond {
Ok(first.clone())
} else {
Ok(second.clone())
}
if cond { Ok(first.clone()) } else { Ok(second.clone()) }
} else {
let first_gadget = first.allocated(&mut cs)?;
let second_gadget = second.allocated(&mut cs)?;
@ -264,10 +240,7 @@ impl<F: Field + PrimeField> ToBitsGadget<F> for FieldType<F> {
self_gadget.to_bits(cs)
}
fn to_bits_strict<CS: ConstraintSystem<F>>(
&self,
mut cs: CS,
) -> Result<Vec<Boolean>, SynthesisError> {
fn to_bits_strict<CS: ConstraintSystem<F>>(&self, mut cs: CS) -> Result<Vec<Boolean>, SynthesisError> {
let self_gadget = self.allocated(&mut cs)?;
self_gadget.to_bits_strict(cs)
}
@ -279,10 +252,7 @@ impl<F: Field + PrimeField> ToBytesGadget<F> for FieldType<F> {
self_gadget.to_bytes(cs)
}
fn to_bytes_strict<CS: ConstraintSystem<F>>(
&self,
mut cs: CS,
) -> Result<Vec<UInt8>, SynthesisError> {
fn to_bytes_strict<CS: ConstraintSystem<F>>(&self, mut cs: CS) -> Result<Vec<UInt8>, SynthesisError> {
let self_gadget = self.allocated(&mut cs)?;
self_gadget.to_bytes_strict(cs)
}

View File

@ -17,7 +17,8 @@ use snarkos_models::{
eq::{ConditionalEqGadget, EqGadget},
select::CondSelectGadget,
uint::UInt8,
ToBitsGadget, ToBytesGadget,
ToBitsGadget,
ToBytesGadget,
},
},
};
@ -43,23 +44,18 @@ impl GroupType<Fq> for EdwardsGroupType {
}
(EdwardsGroupType::Allocated(self_value), EdwardsGroupType::Allocated(other_value)) => {
let result = <EdwardsBlsGadget as GroupGadget<
GroupAffine<EdwardsParameters>,
Fq,
>>::add(self_value, cs, other_value)?;
let result = <EdwardsBlsGadget as GroupGadget<GroupAffine<EdwardsParameters>, Fq>>::add(
self_value,
cs,
other_value,
)?;
Ok(EdwardsGroupType::Allocated(result))
}
(
EdwardsGroupType::Constant(constant_value),
EdwardsGroupType::Allocated(allocated_value),
)
| (
EdwardsGroupType::Allocated(allocated_value),
EdwardsGroupType::Constant(constant_value),
) => Ok(EdwardsGroupType::Allocated(
allocated_value.add_constant(cs, constant_value)?,
)),
(EdwardsGroupType::Constant(constant_value), EdwardsGroupType::Allocated(allocated_value))
| (EdwardsGroupType::Allocated(allocated_value), EdwardsGroupType::Constant(constant_value)) => Ok(
EdwardsGroupType::Allocated(allocated_value.add_constant(cs, constant_value)?),
),
}
}
@ -70,23 +66,18 @@ impl GroupType<Fq> for EdwardsGroupType {
}
(EdwardsGroupType::Allocated(self_value), EdwardsGroupType::Allocated(other_value)) => {
let result = <EdwardsBlsGadget as GroupGadget<
GroupAffine<EdwardsParameters>,
Fq,
>>::sub(self_value, cs, other_value)?;
let result = <EdwardsBlsGadget as GroupGadget<GroupAffine<EdwardsParameters>, Fq>>::sub(
self_value,
cs,
other_value,
)?;
Ok(EdwardsGroupType::Allocated(result))
}
(
EdwardsGroupType::Constant(constant_value),
EdwardsGroupType::Allocated(allocated_value),
)
| (
EdwardsGroupType::Allocated(allocated_value),
EdwardsGroupType::Constant(constant_value),
) => Ok(EdwardsGroupType::Allocated(
allocated_value.sub_constant(cs, constant_value)?,
)),
(EdwardsGroupType::Constant(constant_value), EdwardsGroupType::Allocated(allocated_value))
| (EdwardsGroupType::Allocated(allocated_value), EdwardsGroupType::Constant(constant_value)) => Ok(
EdwardsGroupType::Allocated(allocated_value.sub_constant(cs, constant_value)?),
),
}
}
}
@ -114,10 +105,7 @@ impl EdwardsGroupType {
Self::edwards_affine_from_str(affine_string).map_err(|_| SynthesisError::AssignmentMissing)
}
pub fn allocated<CS: ConstraintSystem<Fq>>(
&self,
mut cs: CS,
) -> Result<EdwardsBlsGadget, SynthesisError> {
pub fn allocated<CS: ConstraintSystem<Fq>>(&self, mut cs: CS) -> Result<EdwardsBlsGadget, SynthesisError> {
match self {
EdwardsGroupType::Constant(constant) => {
<EdwardsBlsGadget as AllocGadget<GroupAffine<EdwardsParameters>, Fq>>::alloc(
@ -131,35 +119,24 @@ impl EdwardsGroupType {
}
impl AllocGadget<String, Fq> for EdwardsGroupType {
fn alloc<
Fn: FnOnce() -> Result<T, SynthesisError>,
T: Borrow<String>,
CS: ConstraintSystem<Fq>,
>(
fn alloc<Fn: FnOnce() -> Result<T, SynthesisError>, T: Borrow<String>, CS: ConstraintSystem<Fq>>(
cs: CS,
value_gen: Fn,
) -> Result<Self, SynthesisError> {
let value = <EdwardsBlsGadget as AllocGadget<GroupAffine<EdwardsParameters>, Fq>>::alloc(
cs,
|| Self::alloc_x_helper(value_gen),
)?;
let value = <EdwardsBlsGadget as AllocGadget<GroupAffine<EdwardsParameters>, Fq>>::alloc(cs, || {
Self::alloc_x_helper(value_gen)
})?;
Ok(EdwardsGroupType::Allocated(value))
}
fn alloc_input<
Fn: FnOnce() -> Result<T, SynthesisError>,
T: Borrow<String>,
CS: ConstraintSystem<Fq>,
>(
fn alloc_input<Fn: FnOnce() -> Result<T, SynthesisError>, T: Borrow<String>, CS: ConstraintSystem<Fq>>(
cs: CS,
value_gen: Fn,
) -> Result<Self, SynthesisError> {
let value =
<EdwardsBlsGadget as AllocGadget<GroupAffine<EdwardsParameters>, Fq>>::alloc_input(
cs,
|| Self::alloc_x_helper(value_gen),
)?;
let value = <EdwardsBlsGadget as AllocGadget<GroupAffine<EdwardsParameters>, Fq>>::alloc_input(cs, || {
Self::alloc_x_helper(value_gen)
})?;
Ok(EdwardsGroupType::Allocated(value))
}
@ -176,18 +153,12 @@ impl PartialEq for EdwardsGroupType {
self_value.eq(other_value)
}
(
EdwardsGroupType::Constant(constant_value),
EdwardsGroupType::Allocated(allocated_value),
)
| (
EdwardsGroupType::Allocated(allocated_value),
EdwardsGroupType::Constant(constant_value),
) => <EdwardsBlsGadget as GroupGadget<GroupAffine<EdwardsParameters>, Fq>>::get_value(
allocated_value,
)
.map(|allocated_value| allocated_value == *constant_value)
.unwrap_or(false),
(EdwardsGroupType::Constant(constant_value), EdwardsGroupType::Allocated(allocated_value))
| (EdwardsGroupType::Allocated(allocated_value), EdwardsGroupType::Constant(constant_value)) => {
<EdwardsBlsGadget as GroupGadget<GroupAffine<EdwardsParameters>, Fq>>::get_value(allocated_value)
.map(|allocated_value| allocated_value == *constant_value)
.unwrap_or(false)
}
}
}
}
@ -214,22 +185,11 @@ impl ConditionalEqGadget<Fq> for EdwardsGroupType {
}
// a - a
(EdwardsGroupType::Allocated(self_value), EdwardsGroupType::Allocated(other_value)) => {
<EdwardsBlsGadget>::conditional_enforce_equal(
self_value,
cs,
other_value,
condition,
)
<EdwardsBlsGadget>::conditional_enforce_equal(self_value, cs, other_value, condition)
}
// c - a = a - c
(
EdwardsGroupType::Constant(constant_value),
EdwardsGroupType::Allocated(allocated_value),
)
| (
EdwardsGroupType::Allocated(allocated_value),
EdwardsGroupType::Constant(constant_value),
) => {
(EdwardsGroupType::Constant(constant_value), EdwardsGroupType::Allocated(allocated_value))
| (EdwardsGroupType::Allocated(allocated_value), EdwardsGroupType::Constant(constant_value)) => {
let x = FpGadget::from(&mut cs, &constant_value.x);
let y = FpGadget::from(&mut cs, &constant_value.y);
let constant_gadget = EdwardsBlsGadget::new(x, y);
@ -252,16 +212,11 @@ impl CondSelectGadget<Fq> for EdwardsGroupType {
second: &Self,
) -> Result<Self, SynthesisError> {
if let Boolean::Constant(cond) = *cond {
if cond {
Ok(first.clone())
} else {
Ok(second.clone())
}
if cond { Ok(first.clone()) } else { Ok(second.clone()) }
} else {
let first_gadget = first.allocated(&mut cs)?;
let second_gadget = second.allocated(&mut cs)?;
let result =
EdwardsBlsGadget::conditionally_select(cs, cond, &first_gadget, &second_gadget)?;
let result = EdwardsBlsGadget::conditionally_select(cs, cond, &first_gadget, &second_gadget)?;
Ok(EdwardsGroupType::Allocated(result))
}
@ -273,18 +228,12 @@ impl CondSelectGadget<Fq> for EdwardsGroupType {
}
impl ToBitsGadget<Fq> for EdwardsGroupType {
fn to_bits<CS: ConstraintSystem<Fq>>(
&self,
mut cs: CS,
) -> Result<Vec<Boolean>, SynthesisError> {
fn to_bits<CS: ConstraintSystem<Fq>>(&self, mut cs: CS) -> Result<Vec<Boolean>, SynthesisError> {
let self_gadget = self.allocated(&mut cs)?;
self_gadget.to_bits(cs)
}
fn to_bits_strict<CS: ConstraintSystem<Fq>>(
&self,
mut cs: CS,
) -> Result<Vec<Boolean>, SynthesisError> {
fn to_bits_strict<CS: ConstraintSystem<Fq>>(&self, mut cs: CS) -> Result<Vec<Boolean>, SynthesisError> {
let self_gadget = self.allocated(&mut cs)?;
self_gadget.to_bits_strict(cs)
}
@ -296,10 +245,7 @@ impl ToBytesGadget<Fq> for EdwardsGroupType {
self_gadget.to_bytes(cs)
}
fn to_bytes_strict<CS: ConstraintSystem<Fq>>(
&self,
mut cs: CS,
) -> Result<Vec<UInt8>, SynthesisError> {
fn to_bytes_strict<CS: ConstraintSystem<Fq>>(&self, mut cs: CS) -> Result<Vec<UInt8>, SynthesisError> {
let self_gadget = self.allocated(&mut cs)?;
self_gadget.to_bytes_strict(cs)
}

View File

@ -10,7 +10,8 @@ use snarkos_models::{
alloc::AllocGadget,
eq::{ConditionalEqGadget, EqGadget},
select::CondSelectGadget,
ToBitsGadget, ToBytesGadget,
ToBitsGadget,
ToBytesGadget,
},
},
};

View File

@ -1,4 +1,4 @@
use crate::{compile_program, get_error, get_output, EdwardsConstrainedValue, EdwardsTestCompiler};
use crate::{get_error, get_output, parse_program, EdwardsConstrainedValue, EdwardsTestCompiler};
use leo_compiler::{
errors::{CompilerError, FunctionError},
ConstrainedValue,
@ -7,15 +7,16 @@ use leo_types::{InputValue, Integer, IntegerError};
use snarkos_models::gadgets::utilities::uint::UInt32;
const DIRECTORY_NAME: &str = "tests/array/";
// [1, 1, 1]
fn output_ones(program: EdwardsTestCompiler) {
let output = get_output(program);
assert_eq!(
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Array(
vec![ConstrainedValue::Integer(Integer::U32(UInt32::constant(1u32))); 3]
)])
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Array(vec![
ConstrainedValue::Integer(
Integer::U32(UInt32::constant(1u32))
);
3
])])
.to_string(),
output.to_string()
);
@ -46,9 +47,7 @@ fn fail_array(program: EdwardsTestCompiler) {
fn fail_synthesis(program: EdwardsTestCompiler) {
match get_error(program) {
CompilerError::FunctionError(FunctionError::IntegerError(
IntegerError::SynthesisError(_string),
)) => {}
CompilerError::FunctionError(FunctionError::IntegerError(IntegerError::SynthesisError(_string))) => {}
error => panic!("Expected synthesis error, got {}", error),
}
}
@ -57,31 +56,41 @@ fn fail_synthesis(program: EdwardsTestCompiler) {
#[test]
fn test_inline() {
let program = compile_program(DIRECTORY_NAME, "inline.leo").unwrap();
let bytes = include_bytes!("inline.leo");
let program = parse_program(bytes).unwrap();
output_ones(program);
}
#[test]
fn test_initializer() {
let program = compile_program(DIRECTORY_NAME, "initializer.leo").unwrap();
let bytes = include_bytes!("initializer.leo");
let program = parse_program(bytes).unwrap();
output_ones(program);
}
#[test]
fn test_spread() {
let program = compile_program(DIRECTORY_NAME, "spread.leo").unwrap();
let bytes = include_bytes!("spread.leo");
let program = parse_program(bytes).unwrap();
output_ones(program);
}
#[test]
fn test_slice() {
let program = compile_program(DIRECTORY_NAME, "slice.leo").unwrap();
let bytes = include_bytes!("slice.leo");
let program = parse_program(bytes).unwrap();
output_ones(program);
}
#[test]
fn test_multi() {
let program = compile_program(DIRECTORY_NAME, "multi.leo").unwrap();
let bytes = include_bytes!("multi.leo");
let program = parse_program(bytes).unwrap();
output_multi(program);
}
@ -89,26 +98,30 @@ fn test_multi() {
#[test]
fn test_input_array() {
let mut program = compile_program(DIRECTORY_NAME, "input_array.leo").unwrap();
program.set_inputs(vec![Some(InputValue::Array(vec![
InputValue::Integer(
1u128
);
3
]))]);
let bytes = include_bytes!("input.leo");
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![Some(InputValue::Array(vec![InputValue::Integer(1u128); 3]))]);
output_ones(program)
}
#[test]
fn test_input_array_fail() {
let mut program = compile_program(DIRECTORY_NAME, "input_array.leo").unwrap();
let bytes = include_bytes!("input.leo");
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![Some(InputValue::Integer(1u128))]);
fail_array(program);
}
#[test]
fn test_input_field_none() {
let mut program = compile_program(DIRECTORY_NAME, "input_array.leo").unwrap();
let bytes = include_bytes!("input.leo");
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![None]);
fail_synthesis(program)
}

View File

@ -1,4 +1,4 @@
use crate::{compile_program, get_error, get_output, EdwardsConstrainedValue, EdwardsTestCompiler};
use crate::{get_error, get_output, parse_program, EdwardsConstrainedValue, EdwardsTestCompiler};
use leo_compiler::{
errors::{BooleanError, CompilerError, ExpressionError, FunctionError, StatementError},
ConstrainedValue,
@ -7,15 +7,10 @@ use leo_types::InputValue;
use snarkos_models::gadgets::utilities::boolean::Boolean;
const DIRECTORY_NAME: &str = "tests/boolean/";
pub fn output_expected_boolean(program: EdwardsTestCompiler, boolean: bool) {
let output = get_output(program);
assert_eq!(
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Boolean(Boolean::Constant(
boolean
))])
.to_string(),
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Boolean(Boolean::Constant(boolean))]).to_string(),
output.to_string()
);
}
@ -30,67 +25,69 @@ pub fn output_false(program: EdwardsTestCompiler) {
fn fail_evaluate(program: EdwardsTestCompiler) {
match get_error(program) {
CompilerError::FunctionError(FunctionError::StatementError(
StatementError::ExpressionError(ExpressionError::BooleanError(
BooleanError::CannotEvaluate(_string),
)),
)) => {}
CompilerError::FunctionError(FunctionError::StatementError(StatementError::ExpressionError(
ExpressionError::BooleanError(BooleanError::CannotEvaluate(_string)),
))) => {}
error => panic!("Expected evaluate error, got {}", error),
}
}
fn fail_enforce(program: EdwardsTestCompiler) {
match get_error(program) {
CompilerError::FunctionError(FunctionError::StatementError(
StatementError::ExpressionError(ExpressionError::BooleanError(
BooleanError::CannotEnforce(_string),
)),
)) => {}
CompilerError::FunctionError(FunctionError::StatementError(StatementError::ExpressionError(
ExpressionError::BooleanError(BooleanError::CannotEnforce(_string)),
))) => {}
error => panic!("Expected evaluate error, got {}", error),
}
}
fn fail_boolean(program: EdwardsTestCompiler) {
match get_error(program) {
CompilerError::FunctionError(FunctionError::BooleanError(
BooleanError::InvalidBoolean(_string),
)) => {}
CompilerError::FunctionError(FunctionError::BooleanError(BooleanError::InvalidBoolean(_string))) => {}
error => panic!("Expected invalid boolean error, got {}", error),
}
}
fn fail_synthesis(program: EdwardsTestCompiler) {
match get_error(program) {
CompilerError::FunctionError(FunctionError::BooleanError(
BooleanError::SynthesisError(_string),
)) => {}
CompilerError::FunctionError(FunctionError::BooleanError(BooleanError::SynthesisError(_string))) => {}
error => panic!("Expected synthesis error, got {}", error),
}
}
#[test]
fn test_true() {
let program = compile_program(DIRECTORY_NAME, "true.leo").unwrap();
let bytes = include_bytes!("true.leo");
let program = parse_program(bytes).unwrap();
output_true(program);
}
#[test]
fn test_false() {
let program = compile_program(DIRECTORY_NAME, "false.leo").unwrap();
let bytes = include_bytes!("false.leo");
let program = parse_program(bytes).unwrap();
output_false(program);
}
#[test]
fn test_input_bool_field() {
let mut program = compile_program(DIRECTORY_NAME, "input_bool.leo").unwrap();
let bytes = include_bytes!("input_bool.leo");
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![Some(InputValue::Integer(1u128))]);
fail_boolean(program);
}
#[test]
fn test_input_bool_none() {
let mut program = compile_program(DIRECTORY_NAME, "input_bool.leo").unwrap();
let bytes = include_bytes!("input_bool.leo");
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![None]);
fail_synthesis(program);
}
@ -98,19 +95,25 @@ fn test_input_bool_none() {
#[test]
fn test_not_true() {
let program = compile_program(DIRECTORY_NAME, "not_true.leo").unwrap();
let bytes = include_bytes!("not_true.leo");
let program = parse_program(bytes).unwrap();
output_false(program);
}
#[test]
fn test_not_false() {
let program = compile_program(DIRECTORY_NAME, "not_false.leo").unwrap();
let bytes = include_bytes!("not_false.leo");
let program = parse_program(bytes).unwrap();
output_true(program);
}
#[test]
fn test_not_u32() {
let program = compile_program(DIRECTORY_NAME, "not_u32.leo").unwrap();
let bytes = include_bytes!("not_u32.leo");
let program = parse_program(bytes).unwrap();
fail_evaluate(program);
}
@ -118,25 +121,33 @@ fn test_not_u32() {
#[test]
fn test_true_or_true() {
let program = compile_program(DIRECTORY_NAME, "true_||_true.leo").unwrap();
let bytes = include_bytes!("true_||_true.leo");
let program = parse_program(bytes).unwrap();
output_true(program);
}
#[test]
fn test_true_or_false() {
let program = compile_program(DIRECTORY_NAME, "true_||_false.leo").unwrap();
let bytes = include_bytes!("true_||_false.leo");
let program = parse_program(bytes).unwrap();
output_true(program);
}
#[test]
fn test_false_or_false() {
let program = compile_program(DIRECTORY_NAME, "false_||_false.leo").unwrap();
let bytes = include_bytes!("false_||_false.leo");
let program = parse_program(bytes).unwrap();
output_false(program);
}
#[test]
fn test_true_or_u32() {
let program = compile_program(DIRECTORY_NAME, "true_||_u32.leo").unwrap();
let bytes = include_bytes!("true_||_u32.leo");
let program = parse_program(bytes).unwrap();
fail_enforce(program);
}
@ -144,25 +155,33 @@ fn test_true_or_u32() {
#[test]
fn test_true_and_true() {
let program = compile_program(DIRECTORY_NAME, "true_&&_true.leo").unwrap();
let bytes = include_bytes!("true_&&_true.leo");
let program = parse_program(bytes).unwrap();
output_true(program);
}
#[test]
fn test_true_and_false() {
let program = compile_program(DIRECTORY_NAME, "true_&&_false.leo").unwrap();
let bytes = include_bytes!("true_&&_false.leo");
let program = parse_program(bytes).unwrap();
output_false(program);
}
#[test]
fn test_false_and_false() {
let program = compile_program(DIRECTORY_NAME, "false_&&_false.leo").unwrap();
let bytes = include_bytes!("false_&&_false.leo");
let program = parse_program(bytes).unwrap();
output_false(program);
}
#[test]
fn test_true_and_u32() {
let program = compile_program(DIRECTORY_NAME, "true_&&_u32.leo").unwrap();
let bytes = include_bytes!("true_&&_u32.leo");
let program = parse_program(bytes).unwrap();
fail_enforce(program);
}
@ -170,6 +189,8 @@ fn test_true_and_u32() {
#[test]
fn test_all() {
let program = compile_program(DIRECTORY_NAME, "all.leo").unwrap();
let bytes = include_bytes!("all.leo");
let program = parse_program(bytes).unwrap();
output_false(program);
}

View File

@ -1,18 +1,20 @@
use crate::{
compile_program, get_error, get_output, integers::u32::output_one, EdwardsConstrainedValue,
get_error,
get_output,
integers::u32::output_one,
parse_program,
EdwardsConstrainedValue,
EdwardsTestCompiler,
};
use leo_compiler::{
errors::{CompilerError, ExpressionError, FunctionError, StatementError},
ConstrainedCircuitMember, ConstrainedValue,
ConstrainedCircuitMember,
ConstrainedValue,
};
use leo_types::{Expression, Function, Identifier, Integer,
Statement, Type,};
use leo_types::{Expression, Function, Identifier, Integer, Statement, Type};
use snarkos_models::gadgets::utilities::uint::UInt32;
const DIRECTORY_NAME: &str = "tests/circuits/";
// Circ { x: 1u32 }
fn output_circuit(program: EdwardsTestCompiler) {
let output = get_output(program);
@ -31,18 +33,18 @@ fn output_circuit(program: EdwardsTestCompiler) {
fn fail_expected_member(program: EdwardsTestCompiler) {
match get_error(program) {
CompilerError::FunctionError(FunctionError::StatementError(
StatementError::ExpressionError(ExpressionError::ExpectedCircuitMember(_string)),
)) => {}
CompilerError::FunctionError(FunctionError::StatementError(StatementError::ExpressionError(
ExpressionError::ExpectedCircuitMember(_string),
))) => {}
error => panic!("Expected invalid circuit member error, got {}", error),
}
}
fn fail_undefined_member(program: EdwardsTestCompiler) {
match get_error(program) {
CompilerError::FunctionError(FunctionError::StatementError(
StatementError::ExpressionError(ExpressionError::UndefinedMemberAccess(_, _)),
)) => {}
CompilerError::FunctionError(FunctionError::StatementError(StatementError::ExpressionError(
ExpressionError::UndefinedMemberAccess(_, _),
))) => {}
error => panic!("Expected undefined circuit member error, got {}", error),
}
}
@ -51,23 +53,29 @@ fn fail_undefined_member(program: EdwardsTestCompiler) {
#[test]
fn test_inline() {
let program = compile_program(DIRECTORY_NAME, "inline.leo").unwrap();
let bytes = include_bytes!("inline.leo");
let program = parse_program(bytes).unwrap();
output_circuit(program);
}
#[test]
fn test_inline_fail() {
let program = compile_program(DIRECTORY_NAME, "inline_fail.leo").unwrap();
let bytes = include_bytes!("inline_fail.leo");
let program = parse_program(bytes).unwrap();
fail_expected_member(program)
}
#[test]
fn test_inline_undefined() {
let program = compile_program(DIRECTORY_NAME, "inline_undefined.leo").unwrap();
let bytes = include_bytes!("inline_undefined.leo");
let program = parse_program(bytes).unwrap();
match get_error(program) {
CompilerError::FunctionError(FunctionError::StatementError(
StatementError::ExpressionError(ExpressionError::UndefinedCircuit(_)),
)) => {}
CompilerError::FunctionError(FunctionError::StatementError(StatementError::ExpressionError(
ExpressionError::UndefinedCircuit(_),
))) => {}
error => panic!("Expected undefined circuit error, got {}", error),
}
}
@ -76,62 +84,79 @@ fn test_inline_undefined() {
#[test]
fn test_member_field() {
let program = compile_program(DIRECTORY_NAME, "member_field.leo").unwrap();
let bytes = include_bytes!("member_field.leo");
let program = parse_program(bytes).unwrap();
output_one(program);
}
#[test]
fn test_member_field_fail() {
let program = compile_program(DIRECTORY_NAME, "member_field_fail.leo").unwrap();
let bytes = include_bytes!("member_field_fail.leo");
let program = parse_program(bytes).unwrap();
fail_undefined_member(program);
}
#[test]
fn test_member_function() {
let program = compile_program(DIRECTORY_NAME, "member_function.leo").unwrap();
let bytes = include_bytes!("member_function.leo");
let program = parse_program(bytes).unwrap();
output_one(program);
}
#[test]
fn test_member_function_fail() {
let program = compile_program(DIRECTORY_NAME, "member_function_fail.leo").unwrap();
let bytes = include_bytes!("member_function_fail.leo");
let program = parse_program(bytes).unwrap();
fail_undefined_member(program);
}
#[test]
fn test_member_function_invalid() {
let program = compile_program(DIRECTORY_NAME, "member_function_invalid.leo").unwrap();
let bytes = include_bytes!("member_function_invalid.leo");
let program = parse_program(bytes).unwrap();
match get_error(program) {
CompilerError::FunctionError(FunctionError::StatementError(
StatementError::ExpressionError(ExpressionError::InvalidStaticAccess(_)),
)) => {}
CompilerError::FunctionError(FunctionError::StatementError(StatementError::ExpressionError(
ExpressionError::InvalidStaticAccess(_),
))) => {}
error => panic!("Expected invalid function error, got {}", error),
}
}
#[test]
fn test_member_static_function() {
let program = compile_program(DIRECTORY_NAME, "member_static_function.leo").unwrap();
let bytes = include_bytes!("member_static_function.leo");
let program = parse_program(bytes).unwrap();
output_one(program);
}
#[test]
fn test_member_static_function_undefined() {
let program = compile_program(DIRECTORY_NAME, "member_static_function_undefined.leo").unwrap();
let bytes = include_bytes!("member_static_function_undefined.leo");
let program = parse_program(bytes).unwrap();
match get_error(program) {
CompilerError::FunctionError(FunctionError::StatementError(
StatementError::ExpressionError(ExpressionError::UndefinedStaticAccess(_, _)),
)) => {}
CompilerError::FunctionError(FunctionError::StatementError(StatementError::ExpressionError(
ExpressionError::UndefinedStaticAccess(_, _),
))) => {}
error => panic!("Expected undefined static function error, got {}", error),
}
}
#[test]
fn test_member_static_function_invalid() {
let program = compile_program(DIRECTORY_NAME, "member_static_function_invalid.leo").unwrap();
let bytes = include_bytes!("member_static_function_invalid.leo");
let program = parse_program(bytes).unwrap();
match get_error(program) {
CompilerError::FunctionError(FunctionError::StatementError(
StatementError::ExpressionError(ExpressionError::InvalidMemberAccess(_)),
)) => {}
CompilerError::FunctionError(FunctionError::StatementError(StatementError::ExpressionError(
ExpressionError::InvalidMemberAccess(_),
))) => {}
error => panic!("Expected invalid static function error, got {}", error),
}
}
@ -139,7 +164,9 @@ fn test_member_static_function_invalid() {
// Self
#[test]
fn test_self() {
let program = compile_program(DIRECTORY_NAME, "self.leo").unwrap();
let bytes = include_bytes!("self.leo");
let program = parse_program(bytes).unwrap();
let output = get_output(program);
// circuit Circ {

View File

@ -1,29 +1,33 @@
use crate::boolean::{output_expected_boolean, output_false, output_true};
use crate::{compile_program, get_error, get_output, EdwardsConstrainedValue, EdwardsTestCompiler};
use crate::{
boolean::{output_expected_boolean, output_false, output_true},
get_error,
get_output,
parse_program,
EdwardsConstrainedValue,
EdwardsTestCompiler,
};
use leo_compiler::{
errors::{CompilerError, FieldError, FunctionError},
ConstrainedValue, FieldType,
ConstrainedValue,
FieldType,
};
use leo_types::InputValue;
use snarkos_curves::edwards_bls12::Fq;
use snarkos_gadgets::curves::edwards_bls12::FqGadget;
use snarkos_models::curves::{Field, PrimeField};
use snarkos_models::gadgets::{
curves::field::FieldGadget,
r1cs::{ConstraintSystem, TestConstraintSystem},
use snarkos_models::{
curves::{Field, PrimeField},
gadgets::{
curves::field::FieldGadget,
r1cs::{ConstraintSystem, TestConstraintSystem},
},
};
use snarkos_utilities::biginteger::BigInteger256;
const DIRECTORY_NAME: &str = "tests/field/";
fn output_expected_constant(program: EdwardsTestCompiler, expected: Fq) {
let output = get_output(program);
assert_eq!(
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Field(FieldType::Constant(
expected
))])
.to_string(),
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Field(FieldType::Constant(expected))]).to_string(),
output.to_string()
);
}
@ -33,9 +37,7 @@ fn output_expected_allocated(program: EdwardsTestCompiler, expected: FqGadget) {
match output {
EdwardsConstrainedValue::Return(vec) => match vec.as_slice() {
[ConstrainedValue::Field(FieldType::Allocated(fp_gadget))] => {
assert_eq!(*fp_gadget, expected as FqGadget)
}
[ConstrainedValue::Field(FieldType::Allocated(fp_gadget))] => assert_eq!(*fp_gadget, expected as FqGadget),
_ => panic!("program output unknown return value"),
},
_ => panic!("program output unknown return value"),
@ -59,28 +61,32 @@ fn fail_field(program: EdwardsTestCompiler) {
fn fail_synthesis(program: EdwardsTestCompiler) {
match get_error(program) {
CompilerError::FunctionError(FunctionError::FieldError(FieldError::SynthesisError(
_string,
))) => {}
CompilerError::FunctionError(FunctionError::FieldError(FieldError::SynthesisError(_string))) => {}
error => panic!("Expected synthesis error, got {}", error),
}
}
#[test]
fn test_zero() {
let program = compile_program(DIRECTORY_NAME, "zero.leo").unwrap();
let bytes = include_bytes!("zero.leo");
let program = parse_program(bytes).unwrap();
output_zero(program);
}
#[test]
fn test_one() {
let program = compile_program(DIRECTORY_NAME, "one.leo").unwrap();
let bytes = include_bytes!("one.leo");
let program = parse_program(bytes).unwrap();
output_one(program);
}
#[test]
fn test_input_pass() {
let mut program = compile_program(DIRECTORY_NAME, "input.leo").unwrap();
let bytes = include_bytes!("input.leo");
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![Some(InputValue::Field("1".into()))]);
let cs = TestConstraintSystem::<Fq>::new();
@ -91,14 +97,18 @@ fn test_input_pass() {
#[test]
fn test_input_fail_bool() {
let mut program = compile_program(DIRECTORY_NAME, "input.leo").unwrap();
let bytes = include_bytes!("input.leo");
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![Some(InputValue::Boolean(true))]);
fail_field(program);
}
#[test]
fn test_input_fail_none() {
let mut program = compile_program(DIRECTORY_NAME, "input.leo").unwrap();
let bytes = include_bytes!("input.leo");
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![None]);
fail_synthesis(program);
}
@ -122,7 +132,9 @@ fn test_add() {
let cs = TestConstraintSystem::<Fq>::new();
let sum_allocated = FqGadget::from(cs, &sum);
let mut program = compile_program(DIRECTORY_NAME, "add.leo").unwrap();
let bytes = include_bytes!("add.leo");
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![
Some(InputValue::Field(r1.to_string())),
Some(InputValue::Field(r2.to_string())),
@ -151,7 +163,9 @@ fn test_sub() {
let cs = TestConstraintSystem::<Fq>::new();
let difference_allocated = FqGadget::from(cs, &difference);
let mut program = compile_program(DIRECTORY_NAME, "sub.leo").unwrap();
let bytes = include_bytes!("sub.leo");
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![
Some(InputValue::Field(r1.to_string())),
Some(InputValue::Field(r2.to_string())),
@ -180,7 +194,9 @@ fn test_mul() {
let cs = TestConstraintSystem::<Fq>::new();
let product_allocated = FqGadget::from(cs, &product);
let mut program = compile_program(DIRECTORY_NAME, "mul.leo").unwrap();
let bytes = include_bytes!("mul.leo");
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![
Some(InputValue::Field(r1.to_string())),
Some(InputValue::Field(r2.to_string())),
@ -209,7 +225,9 @@ fn test_div() {
let cs = TestConstraintSystem::<Fq>::new();
let quotient_allocated = FqGadget::from(cs, &quotient);
let mut program = compile_program(DIRECTORY_NAME, "div.leo").unwrap();
let bytes = include_bytes!("div.leo");
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![
Some(InputValue::Field(r1.to_string())),
Some(InputValue::Field(r2.to_string())),
@ -225,7 +243,9 @@ fn test_eq() {
let r1: u64 = rand::random();
// test equal
let mut program = compile_program(DIRECTORY_NAME, "eq.leo").unwrap();
let bytes = include_bytes!("eq.leo");
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![
Some(InputValue::Field(r1.to_string())),
Some(InputValue::Field(r1.to_string())),
@ -238,7 +258,8 @@ fn test_eq() {
let result = r1.eq(&r2);
let mut program = compile_program(DIRECTORY_NAME, "eq.leo").unwrap();
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![
Some(InputValue::Field(r1.to_string())),
Some(InputValue::Field(r2.to_string())),
@ -254,7 +275,9 @@ fn test_ge() {
let r1: u64 = rand::random();
// test equal
let mut program = compile_program(DIRECTORY_NAME, "ge.leo").unwrap();
let bytes = include_bytes!("ge.leo");
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![
Some(InputValue::Field(r1.to_string())),
Some(InputValue::Field(r1.to_string())),
@ -267,7 +290,8 @@ fn test_ge() {
let result = r1.ge(&r2);
let mut program = compile_program(DIRECTORY_NAME, "ge.leo").unwrap();
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![
Some(InputValue::Field(r1.to_string())),
Some(InputValue::Field(r2.to_string())),
@ -283,7 +307,9 @@ fn test_gt() {
let r1: u64 = rand::random();
// test equal
let mut program = compile_program(DIRECTORY_NAME, "gt.leo").unwrap();
let bytes = include_bytes!("gt.leo");
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![
Some(InputValue::Field(r1.to_string())),
Some(InputValue::Field(r1.to_string())),
@ -296,7 +322,8 @@ fn test_gt() {
let result = r1.gt(&r2);
let mut program = compile_program(DIRECTORY_NAME, "gt.leo").unwrap();
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![
Some(InputValue::Field(r1.to_string())),
Some(InputValue::Field(r2.to_string())),
@ -312,7 +339,9 @@ fn test_le() {
let r1: u64 = rand::random();
// test equal
let mut program = compile_program(DIRECTORY_NAME, "le.leo").unwrap();
let bytes = include_bytes!("le.leo");
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![
Some(InputValue::Field(r1.to_string())),
Some(InputValue::Field(r1.to_string())),
@ -325,7 +354,8 @@ fn test_le() {
let result = r1.le(&r2);
let mut program = compile_program(DIRECTORY_NAME, "le.leo").unwrap();
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![
Some(InputValue::Field(r1.to_string())),
Some(InputValue::Field(r2.to_string())),
@ -341,7 +371,9 @@ fn test_lt() {
let r1: u64 = rand::random();
// test equal
let mut program = compile_program(DIRECTORY_NAME, "lt.leo").unwrap();
let bytes = include_bytes!("lt.leo");
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![
Some(InputValue::Field(r1.to_string())),
Some(InputValue::Field(r1.to_string())),
@ -354,7 +386,8 @@ fn test_lt() {
let result = r1.lt(&r2);
let mut program = compile_program(DIRECTORY_NAME, "lt.leo").unwrap();
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![
Some(InputValue::Field(r1.to_string())),
Some(InputValue::Field(r2.to_string())),
@ -369,7 +402,9 @@ fn test_assert_eq_pass() {
for _ in 0..10 {
let r1: u64 = rand::random();
let mut program = compile_program(DIRECTORY_NAME, "assert_eq.leo").unwrap();
let bytes = include_bytes!("assert_eq.leo");
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![
Some(InputValue::Field(r1.to_string())),
Some(InputValue::Field(r1.to_string())),
@ -389,7 +424,9 @@ fn test_assert_eq_fail() {
continue;
}
let mut program = compile_program(DIRECTORY_NAME, "assert_eq.leo").unwrap();
let bytes = include_bytes!("assert_eq.leo");
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![
Some(InputValue::Field(r1.to_string())),
Some(InputValue::Field(r2.to_string())),
@ -416,7 +453,8 @@ fn test_ternary() {
let g1 = FqGadget::from(cs.ns(|| "g1"), &f1);
let g2 = FqGadget::from(cs.ns(|| "g2"), &f2);
let mut program_1 = compile_program(DIRECTORY_NAME, "ternary.leo").unwrap();
let bytes = include_bytes!("ternary.leo");
let mut program_1 = parse_program(bytes).unwrap();
let mut program_2 = program_1.clone();
// true -> field 1

View File

@ -1,5 +1,9 @@
use crate::{
compile_program, get_error, get_output, integers::u32::output_one, EdwardsConstrainedValue,
get_error,
get_output,
integers::u32::output_one,
parse_program,
EdwardsConstrainedValue,
EdwardsTestCompiler,
};
use leo_compiler::{
@ -9,14 +13,9 @@ use leo_compiler::{
use snarkos_models::gadgets::utilities::boolean::Boolean;
const DIRECTORY_NAME: &str = "tests/function/";
pub(crate) fn output_empty(program: EdwardsTestCompiler) {
let output = get_output(program);
assert_eq!(
EdwardsConstrainedValue::Return(vec![]).to_string(),
output.to_string()
);
assert_eq!(EdwardsConstrainedValue::Return(vec![]).to_string(), output.to_string());
}
// (true, false)
@ -34,9 +33,9 @@ pub(crate) fn output_multiple(program: EdwardsTestCompiler) {
fn fail_undefined_identifier(program: EdwardsTestCompiler) {
match get_error(program) {
CompilerError::FunctionError(FunctionError::StatementError(
StatementError::ExpressionError(ExpressionError::UndefinedIdentifier(_)),
)) => {}
CompilerError::FunctionError(FunctionError::StatementError(StatementError::ExpressionError(
ExpressionError::UndefinedIdentifier(_),
))) => {}
error => panic!("Expected function undefined, got {}", error),
}
}
@ -45,19 +44,25 @@ fn fail_undefined_identifier(program: EdwardsTestCompiler) {
#[test]
fn test_empty() {
let program = compile_program(DIRECTORY_NAME, "empty.leo").unwrap();
let bytes = include_bytes!("empty.leo");
let program = parse_program(bytes).unwrap();
output_empty(program);
}
#[test]
fn test_return() {
let program = compile_program(DIRECTORY_NAME, "return.leo").unwrap();
let bytes = include_bytes!("return.leo");
let program = parse_program(bytes).unwrap();
output_one(program);
}
#[test]
fn test_undefined() {
let program = compile_program(DIRECTORY_NAME, "undefined.leo").unwrap();
let bytes = include_bytes!("undefined.leo");
let program = parse_program(bytes).unwrap();
fail_undefined_identifier(program);
}
@ -65,14 +70,15 @@ fn test_undefined() {
#[test]
fn test_global_scope_fail() {
let program = compile_program(DIRECTORY_NAME, "scope_fail.leo").unwrap();
let bytes = include_bytes!("scope_fail.leo");
let program = parse_program(bytes).unwrap();
match get_error(program) {
CompilerError::FunctionError(FunctionError::StatementError(
StatementError::ExpressionError(ExpressionError::FunctionError(value)),
)) => match *value {
FunctionError::StatementError(StatementError::ExpressionError(
ExpressionError::UndefinedIdentifier(_),
)) => {}
CompilerError::FunctionError(FunctionError::StatementError(StatementError::ExpressionError(
ExpressionError::FunctionError(value),
))) => match *value {
FunctionError::StatementError(StatementError::ExpressionError(ExpressionError::UndefinedIdentifier(_))) => {
}
error => panic!("Expected function undefined, got {}", error),
},
error => panic!("Expected function undefined, got {}", error),
@ -81,7 +87,9 @@ fn test_global_scope_fail() {
#[test]
fn test_value_unchanged() {
let program = compile_program(DIRECTORY_NAME, "value_unchanged.leo").unwrap();
let bytes = include_bytes!("value_unchanged.leo");
let program = parse_program(bytes).unwrap();
output_one(program);
}
@ -89,11 +97,15 @@ fn test_value_unchanged() {
#[test]
fn test_multiple_returns() {
let program = compile_program(DIRECTORY_NAME, "multiple.leo").unwrap();
let bytes = include_bytes!("multiple.leo");
let program = parse_program(bytes).unwrap();
output_multiple(program);
}
#[test]
fn test_multiple_returns_main() {
let program = compile_program(DIRECTORY_NAME, "multiple_main.leo").unwrap();
let bytes = include_bytes!("multiple_main.leo");
let program = parse_program(bytes).unwrap();
output_multiple(program);
}

View File

@ -1,6 +1,10 @@
use crate::{
boolean::{output_false, output_true},
compile_program, fail_enforce, get_output, EdwardsConstrainedValue, EdwardsTestCompiler,
fail_enforce,
get_output,
parse_program,
EdwardsConstrainedValue,
EdwardsTestCompiler,
};
use leo_compiler::{group::edwards_bls12::EdwardsGroupType, ConstrainedValue};
use leo_types::InputValue;
@ -13,18 +17,14 @@ use snarkos_models::{
};
use std::str::FromStr;
const DIRECTORY_NAME: &str = "tests/group/";
const TEST_POINT_1: &str = "(7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)";
const TEST_POINT_2: &str = "(1005842117974384149622370061042978581211342111653966059496918451529532134799, 79389132189982034519597104273449021362784864778548730890166152019533697186)";
fn output_expected_constant(program: EdwardsTestCompiler, expected: EdwardsAffine) {
let output = get_output(program);
assert_eq!(
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Group(EdwardsGroupType::Constant(
expected
))])
.to_string(),
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Group(EdwardsGroupType::Constant(expected))])
.to_string(),
output.to_string()
)
}
@ -49,27 +49,32 @@ fn output_zero(program: EdwardsTestCompiler) {
#[test]
fn test_zero() {
let program = compile_program(DIRECTORY_NAME, "zero.leo").unwrap();
let bytes = include_bytes!("zero.leo");
let program = parse_program(bytes).unwrap();
output_zero(program);
}
#[test]
fn test_point() {
let point = EdwardsAffine::from_str(TEST_POINT_1).unwrap();
let program = compile_program(DIRECTORY_NAME, "point.leo").unwrap();
let bytes = include_bytes!("point.leo");
let program = parse_program(bytes).unwrap();
output_expected_constant(program, point);
}
#[test]
fn test_input() {
let mut program = compile_program(DIRECTORY_NAME, "input.leo").unwrap();
let bytes = include_bytes!("input.leo");
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![Some(InputValue::Group(TEST_POINT_1.into()))]);
let mut cs = TestConstraintSystem::<Fq>::new();
let constant_point = EdwardsAffine::from_str(TEST_POINT_1).unwrap();
let allocated_point =
<EdwardsBlsGadget as AllocGadget<EdwardsAffine, Fq>>::alloc(&mut cs, || Ok(constant_point))
.unwrap();
<EdwardsBlsGadget as AllocGadget<EdwardsAffine, Fq>>::alloc(&mut cs, || Ok(constant_point)).unwrap();
output_expected_allocated(program, allocated_point);
}
@ -83,7 +88,9 @@ fn test_add() {
let sum = point_1.add(&point_2);
let program = compile_program(DIRECTORY_NAME, "add.leo").unwrap();
let bytes = include_bytes!("add.leo");
let program = parse_program(bytes).unwrap();
output_expected_constant(program, sum);
}
@ -96,37 +103,48 @@ fn test_sub() {
let sum = point_1.sub(&point_2);
let program = compile_program(DIRECTORY_NAME, "sub.leo").unwrap();
let bytes = include_bytes!("sub.leo");
let program = parse_program(bytes).unwrap();
output_expected_constant(program, sum);
}
#[test]
fn test_eq_true() {
let program = compile_program(DIRECTORY_NAME, "eq_true.leo").unwrap();
let bytes = include_bytes!("eq_true.leo");
let program = parse_program(bytes).unwrap();
output_true(program)
}
#[test]
fn test_eq_false() {
let program = compile_program(DIRECTORY_NAME, "eq_false.leo").unwrap();
let bytes = include_bytes!("eq_false.leo");
let program = parse_program(bytes).unwrap();
output_false(program)
}
#[test]
fn test_assert_eq_pass() {
let program = compile_program(DIRECTORY_NAME, "assert_eq_true.leo").unwrap();
let bytes = include_bytes!("assert_eq_true.leo");
let program = parse_program(bytes).unwrap();
let _res = get_output(program);
}
#[test]
fn test_assert_eq_fail() {
let program = compile_program(DIRECTORY_NAME, "assert_eq_false.leo").unwrap();
let bytes = include_bytes!("assert_eq_false.leo");
let program = parse_program(bytes).unwrap();
fail_enforce(program);
}
#[test]
fn test_ternary() {
let mut program_1 = compile_program(DIRECTORY_NAME, "ternary.leo").unwrap();
let bytes = include_bytes!("ternary.leo");
let mut program_1 = parse_program(bytes).unwrap();
let mut program_2 = program_1.clone();
// true -> point_1
@ -135,8 +153,7 @@ fn test_ternary() {
let mut cs = TestConstraintSystem::<Fq>::new();
let point_1 = EdwardsAffine::from_str(TEST_POINT_1).unwrap();
let expected_point_1 =
<EdwardsBlsGadget as AllocGadget<EdwardsAffine, Fq>>::alloc(&mut cs, || Ok(point_1))
.unwrap();
<EdwardsBlsGadget as AllocGadget<EdwardsAffine, Fq>>::alloc(&mut cs, || Ok(point_1)).unwrap();
output_expected_allocated(program_1, expected_point_1);
// false -> point_2
@ -145,7 +162,6 @@ fn test_ternary() {
let mut cs = TestConstraintSystem::<Fq>::new();
let point_2 = EdwardsAffine::from_str(TEST_POINT_2).unwrap();
let expected_point_2 =
<EdwardsBlsGadget as AllocGadget<EdwardsAffine, Fq>>::alloc(&mut cs, || Ok(point_2))
.unwrap();
<EdwardsBlsGadget as AllocGadget<EdwardsAffine, Fq>>::alloc(&mut cs, || Ok(point_2)).unwrap();
output_expected_allocated(program_2, expected_point_2);
}

View File

@ -1,27 +1,39 @@
use crate::{compile_program, integers::u32::output_one};
use crate::{integers::u32::output_one, parse_program};
const DIRECTORY_NAME: &str = "tests/import/";
// Import tests rely on knowledge of local directories. They should be run locally only.
#[test]
#[ignore]
fn test_basic() {
let program = compile_program(DIRECTORY_NAME, "basic.leo").unwrap();
let bytes = include_bytes!("basic.leo");
let program = parse_program(bytes).unwrap();
output_one(program);
}
#[test]
#[ignore]
fn test_multiple() {
let program = compile_program(DIRECTORY_NAME, "multiple.leo").unwrap();
let bytes = include_bytes!("multiple.leo");
let program = parse_program(bytes).unwrap();
output_one(program);
}
#[test]
#[ignore]
fn test_star() {
let program = compile_program(DIRECTORY_NAME, "star.leo").unwrap();
let bytes = include_bytes!("star.leo");
let program = parse_program(bytes).unwrap();
output_one(program);
}
#[test]
#[ignore]
fn test_alias() {
let program = compile_program(DIRECTORY_NAME, "alias.leo").unwrap();
let bytes = include_bytes!("alias.leo");
let program = parse_program(bytes).unwrap();
output_one(program);
}

View File

@ -1,12 +1,13 @@
macro_rules! test_uint {
($name: ident, $_type: ty, $gadget: ty, $directory: expr) => {
($name: ident, $_type: ty, $gadget: ty) => {
pub struct $name {}
impl $name {
fn test_min(min: $_type) {
let min_allocated = <$gadget>::constant(min);
let program = compile_program($directory, "min.leo").unwrap();
let bytes = include_bytes!("min.leo");
let program = parse_program(bytes).unwrap();
output_expected_allocated(program, min_allocated);
}
@ -14,7 +15,8 @@ macro_rules! test_uint {
fn test_max(max: $_type) {
let max_allocated = <$gadget>::constant(max);
let program = compile_program($directory, "max.leo").unwrap();
let bytes = include_bytes!("max.leo");
let program = parse_program(bytes).unwrap();
output_expected_allocated(program, max_allocated);
}
@ -26,18 +28,21 @@ macro_rules! test_uint {
let num: $_type = rand::random();
let expected = <$gadget>::constant(num);
let mut program = compile_program($directory, "input.leo").unwrap();
let bytes = include_bytes!("input.leo");
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![Some(InputValue::Integer(num as u128))]);
output_expected_allocated(program, expected);
// invalid input
let mut program = compile_program($directory, "input.leo").unwrap();
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![Some(InputValue::Boolean(true))]);
fail_integer(program);
// None input
let mut program = compile_program($directory, "input.leo").unwrap();
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![None]);
fail_synthesis(program);
}
@ -52,7 +57,9 @@ macro_rules! test_uint {
let cs = TestConstraintSystem::<Fq>::new();
let sum_allocated = <$gadget>::alloc(cs, || Ok(sum)).unwrap();
let mut program = compile_program($directory, "add.leo").unwrap();
let bytes = include_bytes!("add.leo");
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![
Some(InputValue::Integer(r1 as u128)),
Some(InputValue::Integer(r2 as u128)),
@ -72,7 +79,9 @@ macro_rules! test_uint {
let cs = TestConstraintSystem::<Fq>::new();
let difference_allocated = <$gadget>::alloc(cs, || Ok(difference)).unwrap();
let mut program = compile_program($directory, "sub.leo").unwrap();
let bytes = include_bytes!("sub.leo");
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![
Some(InputValue::Integer(r1 as u128)),
Some(InputValue::Integer(r2 as u128)),
@ -92,7 +101,9 @@ macro_rules! test_uint {
let cs = TestConstraintSystem::<Fq>::new();
let product_allocated = <$gadget>::alloc(cs, || Ok(product)).unwrap();
let mut program = compile_program($directory, "mul.leo").unwrap();
let bytes = include_bytes!("mul.leo");
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![
Some(InputValue::Integer(r1 as u128)),
Some(InputValue::Integer(r2 as u128)),
@ -112,7 +123,9 @@ macro_rules! test_uint {
let cs = TestConstraintSystem::<Fq>::new();
let quotient_allocated = <$gadget>::alloc(cs, || Ok(quotient)).unwrap();
let mut program = compile_program($directory, "div.leo").unwrap();
let bytes = include_bytes!("div.leo");
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![
Some(InputValue::Integer(r1 as u128)),
Some(InputValue::Integer(r2 as u128)),
@ -133,7 +146,9 @@ macro_rules! test_uint {
let cs = TestConstraintSystem::<Fq>::new();
let result_allocated = <$gadget>::alloc(cs, || Ok(result)).unwrap();
let mut program = compile_program($directory, "pow.leo").unwrap();
let bytes = include_bytes!("pow.leo");
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![
Some(InputValue::Integer(r1 as u128)),
Some(InputValue::Integer(r2 as u128)),
@ -148,7 +163,9 @@ macro_rules! test_uint {
let r1: $_type = rand::random();
// test equal
let mut program = compile_program($directory, "eq.leo").unwrap();
let bytes = include_bytes!("eq.leo");
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![
Some(InputValue::Integer(r1 as u128)),
Some(InputValue::Integer(r1 as u128)),
@ -161,7 +178,8 @@ macro_rules! test_uint {
let result = r1.eq(&r2);
let mut program = compile_program($directory, "eq.leo").unwrap();
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![
Some(InputValue::Integer(r1 as u128)),
Some(InputValue::Integer(r2 as u128)),
@ -176,7 +194,9 @@ macro_rules! test_uint {
let r1: $_type = rand::random();
// test equal
let mut program = compile_program($directory, "ge.leo").unwrap();
let bytes = include_bytes!("ge.leo");
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![
Some(InputValue::Integer(r1 as u128)),
Some(InputValue::Integer(r1 as u128)),
@ -189,7 +209,8 @@ macro_rules! test_uint {
let result = r1.ge(&r2);
let mut program = compile_program($directory, "ge.leo").unwrap();
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![
Some(InputValue::Integer(r1 as u128)),
Some(InputValue::Integer(r2 as u128)),
@ -204,7 +225,9 @@ macro_rules! test_uint {
let r1: $_type = rand::random();
// test equal
let mut program = compile_program($directory, "gt.leo").unwrap();
let bytes = include_bytes!("gt.leo");
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![
Some(InputValue::Integer(r1 as u128)),
Some(InputValue::Integer(r1 as u128)),
@ -217,7 +240,8 @@ macro_rules! test_uint {
let result = r1.gt(&r2);
let mut program = compile_program($directory, "gt.leo").unwrap();
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![
Some(InputValue::Integer(r1 as u128)),
Some(InputValue::Integer(r2 as u128)),
@ -232,7 +256,9 @@ macro_rules! test_uint {
let r1: $_type = rand::random();
// test equal
let mut program = compile_program($directory, "le.leo").unwrap();
let bytes = include_bytes!("le.leo");
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![
Some(InputValue::Integer(r1 as u128)),
Some(InputValue::Integer(r1 as u128)),
@ -245,7 +271,8 @@ macro_rules! test_uint {
let result = r1.le(&r2);
let mut program = compile_program($directory, "le.leo").unwrap();
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![
Some(InputValue::Integer(r1 as u128)),
Some(InputValue::Integer(r2 as u128)),
@ -260,7 +287,9 @@ macro_rules! test_uint {
let r1: $_type = rand::random();
// test equal
let mut program = compile_program($directory, "lt.leo").unwrap();
let bytes = include_bytes!("lt.leo");
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![
Some(InputValue::Integer(r1 as u128)),
Some(InputValue::Integer(r1 as u128)),
@ -273,7 +302,8 @@ macro_rules! test_uint {
let result = r1.lt(&r2);
let mut program = compile_program($directory, "lt.leo").unwrap();
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![
Some(InputValue::Integer(r1 as u128)),
Some(InputValue::Integer(r2 as u128)),
@ -288,7 +318,9 @@ macro_rules! test_uint {
let r1: $_type = rand::random();
// test equal
let mut program = compile_program($directory, "assert_eq.leo").unwrap();
let bytes = include_bytes!("assert_eq.leo");
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![
Some(InputValue::Integer(r1 as u128)),
Some(InputValue::Integer(r1 as u128)),
@ -303,7 +335,8 @@ macro_rules! test_uint {
continue;
}
let mut program = compile_program($directory, "assert_eq.leo").unwrap();
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![
Some(InputValue::Integer(r1 as u128)),
Some(InputValue::Integer(r2 as u128)),
@ -322,7 +355,9 @@ macro_rules! test_uint {
let g1 = <$gadget>::constant(r1);
let g2 = <$gadget>::constant(r2);
let mut program_1 = compile_program($directory, "ternary.leo").unwrap();
let bytes = include_bytes!("ternary.leo");
let mut program_1 = parse_program(bytes).unwrap();
let mut program_2 = program_1.clone();
// true -> field 1

View File

@ -48,18 +48,14 @@ pub trait IntegerTester {
pub(crate) fn fail_integer(program: EdwardsTestCompiler) {
match get_error(program) {
CompilerError::FunctionError(FunctionError::IntegerError(
IntegerError::InvalidInteger(_string),
)) => {}
CompilerError::FunctionError(FunctionError::IntegerError(IntegerError::InvalidInteger(_string))) => {}
error => panic!("Expected invalid boolean error, got {}", error),
}
}
pub(crate) fn fail_synthesis(program: EdwardsTestCompiler) {
match get_error(program) {
CompilerError::FunctionError(FunctionError::IntegerError(
IntegerError::SynthesisError(_string),
)) => {}
CompilerError::FunctionError(FunctionError::IntegerError(IntegerError::SynthesisError(_string))) => {}
error => panic!("Expected synthesis error, got {}", error),
}
}

View File

@ -1,17 +1,19 @@
use crate::{
boolean::{output_expected_boolean, output_false, output_true},
compile_program, get_output,
get_output,
integers::{fail_integer, fail_synthesis, IntegerTester},
EdwardsConstrainedValue, EdwardsTestCompiler,
parse_program,
EdwardsConstrainedValue,
EdwardsTestCompiler,
};
use leo_compiler::ConstrainedValue;
use leo_types::{Integer, InputValue};
use leo_types::{InputValue, Integer};
use snarkos_curves::edwards_bls12::Fq;
use snarkos_models::gadgets::r1cs::TestConstraintSystem;
use snarkos_models::gadgets::utilities::{alloc::AllocGadget, uint::UInt128};
const DIRECTORY_NAME: &str = "tests/integers/u128/";
use snarkos_models::gadgets::{
r1cs::TestConstraintSystem,
utilities::{alloc::AllocGadget, uint::UInt128},
};
fn output_expected_allocated(program: EdwardsTestCompiler, expected: UInt128) {
let output = get_output(program);
@ -26,8 +28,9 @@ fn output_expected_allocated(program: EdwardsTestCompiler, expected: UInt128) {
}
#[test]
#[ignore] // temporarily ignore memory expensive tests for travis
fn test_u128() {
test_uint!(TestU128, u128, UInt128, DIRECTORY_NAME);
test_uint!(TestU128, u128, UInt128);
TestU128::test_min(std::u128::MIN);
TestU128::test_max(std::u128::MAX);

View File

@ -1,17 +1,19 @@
use crate::{
boolean::{output_expected_boolean, output_false, output_true},
compile_program, get_output,
get_output,
integers::{fail_integer, fail_synthesis, IntegerTester},
EdwardsConstrainedValue, EdwardsTestCompiler,
parse_program,
EdwardsConstrainedValue,
EdwardsTestCompiler,
};
use leo_compiler::ConstrainedValue;
use leo_types::{Integer, InputValue};
use leo_types::{InputValue, Integer};
use snarkos_curves::edwards_bls12::Fq;
use snarkos_models::gadgets::r1cs::TestConstraintSystem;
use snarkos_models::gadgets::utilities::{alloc::AllocGadget, uint::UInt16};
const DIRECTORY_NAME: &str = "tests/integers/u16/";
use snarkos_models::gadgets::{
r1cs::TestConstraintSystem,
utilities::{alloc::AllocGadget, uint::UInt16},
};
fn output_expected_allocated(program: EdwardsTestCompiler, expected: UInt16) {
let output = get_output(program);
@ -27,7 +29,7 @@ fn output_expected_allocated(program: EdwardsTestCompiler, expected: UInt16) {
#[test]
fn test_u16() {
test_uint!(Testu16, u16, UInt16, DIRECTORY_NAME);
test_uint!(Testu16, u16, UInt16);
Testu16::test_min(std::u16::MIN);
Testu16::test_max(std::u16::MAX);

View File

@ -1,17 +1,19 @@
use crate::{
boolean::{output_expected_boolean, output_false, output_true},
compile_program, get_output,
get_output,
integers::{fail_integer, fail_synthesis, IntegerTester},
EdwardsConstrainedValue, EdwardsTestCompiler,
parse_program,
EdwardsConstrainedValue,
EdwardsTestCompiler,
};
use leo_compiler::ConstrainedValue;
use leo_types::{Integer, InputValue};
use leo_types::{InputValue, Integer};
use snarkos_curves::edwards_bls12::Fq;
use snarkos_models::gadgets::r1cs::TestConstraintSystem;
use snarkos_models::gadgets::utilities::{alloc::AllocGadget, uint::UInt32};
const DIRECTORY_NAME: &str = "tests/integers/u32/";
use snarkos_models::gadgets::{
r1cs::TestConstraintSystem,
utilities::{alloc::AllocGadget, uint::UInt32},
};
fn output_expected_allocated(program: EdwardsTestCompiler, expected: UInt32) {
let output = get_output(program);
@ -28,10 +30,8 @@ fn output_expected_allocated(program: EdwardsTestCompiler, expected: UInt32) {
pub(crate) fn output_zero(program: EdwardsTestCompiler) {
let output = get_output(program);
assert_eq!(
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Integer(Integer::U32(
UInt32::constant(0u32)
))])
.to_string(),
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Integer(Integer::U32(UInt32::constant(0u32)))])
.to_string(),
output.to_string()
)
}
@ -39,17 +39,15 @@ pub(crate) fn output_zero(program: EdwardsTestCompiler) {
pub(crate) fn output_one(program: EdwardsTestCompiler) {
let output = get_output(program);
assert_eq!(
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Integer(Integer::U32(
UInt32::constant(1u32)
))])
.to_string(),
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Integer(Integer::U32(UInt32::constant(1u32)))])
.to_string(),
output.to_string()
)
}
#[test]
fn test_u32() {
test_uint!(TestU32, u32, UInt32, DIRECTORY_NAME);
test_uint!(TestU32, u32, UInt32);
TestU32::test_min(std::u32::MIN);
TestU32::test_max(std::u32::MAX);
@ -74,12 +72,16 @@ fn test_u32() {
#[test]
fn test_zero() {
let program = compile_program(DIRECTORY_NAME, "zero.leo").unwrap();
let bytes = include_bytes!("zero.leo");
let program = parse_program(bytes).unwrap();
output_zero(program);
}
#[test]
fn test_one() {
let program = compile_program(DIRECTORY_NAME, "one.leo").unwrap();
let bytes = include_bytes!("one.leo");
let program = parse_program(bytes).unwrap();
output_one(program);
}

View File

@ -1,17 +1,19 @@
use crate::{
boolean::{output_expected_boolean, output_false, output_true},
compile_program, get_output,
get_output,
integers::{fail_integer, fail_synthesis, IntegerTester},
EdwardsConstrainedValue, EdwardsTestCompiler,
parse_program,
EdwardsConstrainedValue,
EdwardsTestCompiler,
};
use leo_compiler::ConstrainedValue;
use leo_types::{Integer, InputValue};
use leo_types::{InputValue, Integer};
use snarkos_curves::edwards_bls12::Fq;
use snarkos_models::gadgets::r1cs::TestConstraintSystem;
use snarkos_models::gadgets::utilities::{alloc::AllocGadget, uint::UInt64};
const DIRECTORY_NAME: &str = "tests/integers/u64/";
use snarkos_models::gadgets::{
r1cs::TestConstraintSystem,
utilities::{alloc::AllocGadget, uint::UInt64},
};
fn output_expected_allocated(program: EdwardsTestCompiler, expected: UInt64) {
let output = get_output(program);
@ -26,8 +28,9 @@ fn output_expected_allocated(program: EdwardsTestCompiler, expected: UInt64) {
}
#[test]
#[ignore] //temporarily ignore memory expensive tests for travis
fn test_u64() {
test_uint!(Testu64, u64, UInt64, DIRECTORY_NAME);
test_uint!(Testu64, u64, UInt64);
Testu64::test_min(std::u64::MIN);
Testu64::test_max(std::u64::MAX);

View File

@ -1,17 +1,19 @@
use crate::{
boolean::{output_expected_boolean, output_false, output_true},
compile_program, get_output,
get_output,
integers::{fail_integer, fail_synthesis, IntegerTester},
EdwardsConstrainedValue, EdwardsTestCompiler,
parse_program,
EdwardsConstrainedValue,
EdwardsTestCompiler,
};
use leo_compiler::ConstrainedValue;
use leo_types::{Integer, InputValue};
use leo_types::{InputValue, Integer};
use snarkos_curves::edwards_bls12::Fq;
use snarkos_models::gadgets::r1cs::TestConstraintSystem;
use snarkos_models::gadgets::utilities::{alloc::AllocGadget, uint::UInt8};
const DIRECTORY_NAME: &str = "tests/integers/u8/";
use snarkos_models::gadgets::{
r1cs::TestConstraintSystem,
utilities::{alloc::AllocGadget, uint::UInt8},
};
fn output_expected_allocated(program: EdwardsTestCompiler, expected: UInt8) {
let output = get_output(program);
@ -27,7 +29,7 @@ fn output_expected_allocated(program: EdwardsTestCompiler, expected: UInt8) {
#[test]
fn test_u8() {
test_uint!(Testu8, u8, UInt8, DIRECTORY_NAME);
test_uint!(Testu8, u8, UInt8);
Testu8::test_min(std::u8::MIN);
Testu8::test_max(std::u8::MAX);

View File

@ -19,7 +19,6 @@ use leo_compiler::{
use snarkos_curves::edwards_bls12::Fq;
use snarkos_models::gadgets::r1cs::TestConstraintSystem;
use std::env::current_dir;
pub type EdwardsTestCompiler = Compiler<Fq, EdwardsGroupType>;
pub type EdwardsConstrainedValue = ConstrainedValue<Fq, EdwardsGroupType>;
@ -38,32 +37,17 @@ pub(crate) fn get_error(program: EdwardsTestCompiler) -> CompilerError {
pub(crate) fn fail_enforce(program: EdwardsTestCompiler) {
match get_error(program) {
CompilerError::FunctionError(FunctionError::StatementError(
StatementError::AssertionFailed(_, _),
)) => {}
CompilerError::FunctionError(FunctionError::StatementError(StatementError::AssertionFailed(_, _))) => {}
error => panic!("Expected evaluate error, got {}", error),
}
}
pub(crate) fn compile_program(
directory_name: &str,
file_name: &str,
) -> Result<EdwardsTestCompiler, CompilerError> {
let path = current_dir().map_err(|error| CompilerError::DirectoryError(error))?;
pub(crate) fn parse_program(bytes: &[u8]) -> Result<EdwardsTestCompiler, CompilerError> {
let program_string = String::from_utf8_lossy(bytes);
// Sanitize the package path to the test directory
let mut package_path = path.clone();
if package_path.is_file() {
package_path.pop();
}
let mut compiler = EdwardsTestCompiler::new();
// Construct the path to the test file in the test directory
let mut main_file_path = package_path.clone();
main_file_path.push(directory_name);
main_file_path.push(file_name);
compiler.parse_program(&program_string)?;
println!("Compiling file - {:?}", main_file_path);
// Compile from the main file path
EdwardsTestCompiler::init(file_name.to_string(), main_file_path)
Ok(compiler)
}

View File

@ -1,4 +1,4 @@
use crate::{compile_program, EdwardsConstrainedValue, EdwardsTestCompiler};
use crate::{parse_program, EdwardsConstrainedValue, EdwardsTestCompiler};
use leo_compiler::{
errors::{CompilerError, FunctionError, StatementError},
ConstrainedValue,
@ -8,18 +8,13 @@ use leo_types::{InputValue, Integer};
use snarkos_curves::edwards_bls12::Fq;
use snarkos_models::gadgets::{r1cs::TestConstraintSystem, utilities::uint::UInt32};
const DIRECTORY_NAME: &str = "tests/mutability/";
fn mut_success(program: EdwardsTestCompiler) {
let mut cs = TestConstraintSystem::<Fq>::new();
let output = program.compile_constraints(&mut cs).unwrap();
assert!(cs.is_satisfied());
assert_eq!(
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Integer(Integer::U32(
UInt32::constant(0)
))])
.to_string(),
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Integer(Integer::U32(UInt32::constant(0)))]).to_string(),
output.to_string()
);
}
@ -31,59 +26,73 @@ fn mut_fail(program: EdwardsTestCompiler) {
// It would be ideal if assert_eq!(Error1, Error2) were possible but unfortunately it is not due to
// https://github.com/rust-lang/rust/issues/34158#issuecomment-224910299
match err {
CompilerError::FunctionError(FunctionError::StatementError(
StatementError::ImmutableAssign(_string),
)) => {}
CompilerError::FunctionError(FunctionError::StatementError(StatementError::ImmutableAssign(_string))) => {}
err => panic!("Expected immutable assign error, got {}", err),
}
}
#[test]
fn test_let() {
let program = compile_program(DIRECTORY_NAME, "let.leo").unwrap();
let bytes = include_bytes!("let.leo");
let program = parse_program(bytes).unwrap();
mut_fail(program);
}
#[test]
fn test_let_mut() {
let program = compile_program(DIRECTORY_NAME, "let_mut.leo").unwrap();
let bytes = include_bytes!("let_mut.leo");
let program = parse_program(bytes).unwrap();
mut_success(program);
}
#[test]
fn test_array() {
let program = compile_program(DIRECTORY_NAME, "array.leo").unwrap();
let bytes = include_bytes!("array.leo");
let program = parse_program(bytes).unwrap();
mut_fail(program);
}
#[test]
fn test_array_mut() {
let program = compile_program(DIRECTORY_NAME, "array_mut.leo").unwrap();
let bytes = include_bytes!("array_mut.leo");
let program = parse_program(bytes).unwrap();
mut_success(program);
}
#[test]
fn test_circuit() {
let program = compile_program(DIRECTORY_NAME, "circuit.leo").unwrap();
let bytes = include_bytes!("circuit.leo");
let program = parse_program(bytes).unwrap();
mut_fail(program);
}
#[test]
fn test_circuit_mut() {
let program = compile_program(DIRECTORY_NAME, "circuit_mut.leo").unwrap();
let bytes = include_bytes!("circuit_mut.leo");
let program = parse_program(bytes).unwrap();
mut_success(program);
}
#[test]
fn test_function_input() {
let mut program = compile_program(DIRECTORY_NAME, "function_input.leo").unwrap();
let bytes = include_bytes!("function_input.leo");
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![Some(InputValue::Integer(1))]);
mut_fail(program);
}
#[test]
fn test_function_input_mut() {
let mut program = compile_program(DIRECTORY_NAME, "function_input_mut.leo").unwrap();
let bytes = include_bytes!("function_input_mut.leo");
let mut program = parse_program(bytes).unwrap();
program.set_inputs(vec![Some(InputValue::Integer(1))]);
mut_success(program);
}

View File

@ -1,19 +1,19 @@
use crate::{
compile_program,
integers::u32::{output_one, output_zero},
parse_program,
};
use leo_types::InputValue;
use snarkos_curves::edwards_bls12::Fq;
use snarkos_models::gadgets::r1cs::TestConstraintSystem;
const DIRECTORY_NAME: &str = "tests/statements/";
// Ternary if {bool}? {expression} : {expression};
#[test]
fn test_ternary_basic() {
let mut program_input_true = compile_program(DIRECTORY_NAME, "ternary_basic.leo").unwrap();
let bytes = include_bytes!("ternary_basic.leo");
let mut program_input_true = parse_program(bytes).unwrap();
let mut program_input_false = program_input_true.clone();
program_input_true.set_inputs(vec![Some(InputValue::Boolean(true))]);
@ -27,7 +27,9 @@ fn test_ternary_basic() {
#[test]
fn test_iteration_basic() {
let program = compile_program(DIRECTORY_NAME, "iteration_basic.leo").unwrap();
let bytes = include_bytes!("iteration_basic.leo");
let program = parse_program(bytes).unwrap();
output_one(program);
}
@ -35,15 +37,14 @@ fn test_iteration_basic() {
#[test]
fn test_assertion_basic() {
let program = compile_program(DIRECTORY_NAME, "assertion_basic.leo").unwrap();
let bytes = include_bytes!("assertion_basic.leo");
let program = parse_program(bytes).unwrap();
let mut program_input_true = program.clone();
let mut cs_satisfied = TestConstraintSystem::<Fq>::new();
program_input_true.set_inputs(vec![Some(InputValue::Boolean(true))]);
let _output = program_input_true
.compile_constraints(&mut cs_satisfied)
.unwrap();
let _output = program_input_true.compile_constraints(&mut cs_satisfied).unwrap();
assert!(cs_satisfied.is_satisfied());
@ -51,9 +52,7 @@ fn test_assertion_basic() {
let mut cs_unsatisfied = TestConstraintSystem::<Fq>::new();
program_input_false.set_inputs(vec![Some(InputValue::Boolean(false))]);
let _output = program_input_false
.compile_constraints(&mut cs_unsatisfied)
.unwrap();
let _output = program_input_false.compile_constraints(&mut cs_unsatisfied).unwrap();
assert!(!cs_unsatisfied.is_satisfied());
}

View File

@ -1,16 +1,14 @@
use crate::compile_program;
use crate::parse_program;
use leo_ast::ParserError;
use leo_compiler::errors::CompilerError;
const DIRECTORY_NAME: &str = "tests/syntax/";
#[test]
fn test_semicolon() {
let error = compile_program(DIRECTORY_NAME, "semicolon.leo")
.err()
.unwrap();
let bytes = include_bytes!("semicolon.leo");
let error = parse_program(bytes).err().unwrap();
match error {
CompilerError::ParserError(_) => {}
CompilerError::ParserError(ParserError::SyntaxError(_)) => {}
_ => panic!("test_semicolon failed the wrong expected error, should be a ParserError"),
}
}

View File

@ -1,5 +1,4 @@
use crate::cli_types::*;
use crate::errors::CLIError;
use crate::{cli_types::*, errors::CLIError};
use clap::{App, AppSettings, Arg, ArgMatches, SubCommand};
@ -31,9 +30,7 @@ pub trait CLI {
.conflicts_with_all(a.1)
.possible_values(a.2)
.requires_all(a.3),
false => Arg::from_usage(a.0)
.conflicts_with_all(a.1)
.requires_all(a.3),
false => Arg::from_usage(a.0).conflicts_with_all(a.1).requires_all(a.3),
})
.collect::<Vec<Arg<'static, 'static>>>();
let subcommands = Self::SUBCOMMANDS
@ -48,9 +45,7 @@ pub trait CLI {
.conflicts_with_all(a.1)
.possible_values(a.2)
.requires_all(a.3),
false => Arg::from_usage(a.0)
.conflicts_with_all(a.1)
.requires_all(a.3),
false => Arg::from_usage(a.0).conflicts_with_all(a.1).requires_all(a.3),
})
.collect::<Vec<Arg<'static, 'static>>>(),
)

View File

@ -21,9 +21,4 @@ pub type OptionType = (
&'static [&'static str],
);
pub type SubCommandType = (
NameType,
AboutType,
&'static [OptionType],
&'static [AppSettings],
);
pub type SubCommandType = (NameType, AboutType, &'static [OptionType], &'static [AppSettings]);

View File

@ -1,15 +1,17 @@
use crate::directories::{source::SOURCE_DIRECTORY_NAME, OutputsDirectory};
use crate::errors::{BuildError, CLIError};
use crate::files::{ChecksumFile, MainFile, Manifest, MAIN_FILE_NAME};
use crate::{cli::*, cli_types::*};
use crate::{
cli::*,
cli_types::*,
directories::{source::SOURCE_DIRECTORY_NAME, OutputsDirectory},
errors::{BuildError, CLIError},
files::{ChecksumFile, MainFile, Manifest, MAIN_FILE_NAME},
};
use leo_compiler::{compiler::Compiler, group::edwards_bls12::EdwardsGroupType};
use snarkos_algorithms::snark::KeypairAssembly;
use snarkos_curves::{bls12_377::Bls12_377, edwards_bls12::Fq};
use clap::ArgMatches;
use std::convert::TryFrom;
use std::env::current_dir;
use std::{convert::TryFrom, env::current_dir};
#[derive(Debug)]
pub struct BuildCommand;
@ -18,10 +20,10 @@ impl CLI for BuildCommand {
type Options = ();
type Output = (Compiler<Fq, EdwardsGroupType>, bool);
const NAME: NameType = "build";
const ABOUT: AboutType = "Compile the current package as a program";
const ARGUMENTS: &'static [ArgumentType] = &[];
const FLAGS: &'static [FlagType] = &[];
const NAME: NameType = "build";
const OPTIONS: &'static [OptionType] = &[];
const SUBCOMMANDS: &'static [SubCommandType] = &[];
@ -46,9 +48,7 @@ impl CLI for BuildCommand {
// Verify the main file exists
if !MainFile::exists_at(&package_path) {
return Err(
BuildError::MainFileDoesNotExist(package_path.as_os_str().to_owned()).into(),
);
return Err(BuildError::MainFileDoesNotExist(package_path.as_os_str().to_owned()).into());
}
// Create the outputs directory
@ -60,8 +60,7 @@ impl CLI for BuildCommand {
main_file_path.push(MAIN_FILE_NAME);
// Compute the current program checksum
let program =
Compiler::<Fq, EdwardsGroupType>::init(package_name.clone(), main_file_path.clone())?;
let program = Compiler::<Fq, EdwardsGroupType>::init(package_name.clone(), main_file_path.clone())?;
let program_checksum = program.checksum()?;
// Generate the program on the constraint system and verify correctness

View File

@ -1,11 +1,7 @@
use crate::commands::BuildCommand;
use crate::errors::CLIError;
use crate::files::Manifest;
use crate::{cli::*, cli_types::*};
use crate::{cli::*, cli_types::*, commands::BuildCommand, errors::CLIError, files::Manifest};
use clap::ArgMatches;
use std::convert::TryFrom;
use std::env::current_dir;
use std::{convert::TryFrom, env::current_dir};
#[derive(Debug)]
pub struct DeployCommand;
@ -14,10 +10,10 @@ impl CLI for DeployCommand {
type Options = ();
type Output = ();
const NAME: NameType = "deploy";
const ABOUT: AboutType = "Deploy the current package as a program to the network (*)";
const ARGUMENTS: &'static [ArgumentType] = &[];
const FLAGS: &'static [FlagType] = &[];
const NAME: NameType = "deploy";
const OPTIONS: &'static [OptionType] = &[];
const SUBCOMMANDS: &'static [SubCommandType] = &[];

View File

@ -1,7 +1,10 @@
use crate::directories::{InputsDirectory, SourceDirectory};
use crate::errors::{CLIError, InitError};
use crate::files::{Gitignore, MainFile, Manifest};
use crate::{cli::*, cli_types::*};
use crate::{
cli::*,
cli_types::*,
directories::{InputsDirectory, SourceDirectory},
errors::{CLIError, InitError},
files::{Gitignore, MainFile, Manifest},
};
use clap::ArgMatches;
use std::env::current_dir;
@ -13,10 +16,10 @@ impl CLI for InitCommand {
type Options = Option<String>;
type Output = ();
const NAME: NameType = "init";
const ABOUT: AboutType = "Create a new Leo package in an existing directory";
const ARGUMENTS: &'static [ArgumentType] = &[];
const FLAGS: &'static [FlagType] = &[];
const NAME: NameType = "init";
const OPTIONS: &'static [OptionType] = &[];
const SUBCOMMANDS: &'static [SubCommandType] = &[];

View File

@ -1,11 +1,7 @@
use crate::commands::BuildCommand;
use crate::errors::CLIError;
use crate::files::Manifest;
use crate::{cli::*, cli_types::*};
use crate::{cli::*, cli_types::*, commands::BuildCommand, errors::CLIError, files::Manifest};
use clap::ArgMatches;
use std::convert::TryFrom;
use std::env::current_dir;
use std::{convert::TryFrom, env::current_dir};
#[derive(Debug)]
pub struct LoadCommand;
@ -14,10 +10,10 @@ impl CLI for LoadCommand {
type Options = ();
type Output = ();
const NAME: NameType = "load";
const ABOUT: AboutType = "Install a package from the package manager (*)";
const ARGUMENTS: &'static [ArgumentType] = &[];
const FLAGS: &'static [FlagType] = &[];
const NAME: NameType = "load";
const OPTIONS: &'static [OptionType] = &[];
const SUBCOMMANDS: &'static [SubCommandType] = &[];

View File

@ -1,11 +1,13 @@
use crate::directories::{InputsDirectory, SourceDirectory};
use crate::errors::{CLIError, NewError};
use crate::files::{Gitignore, MainFile, Manifest};
use crate::{cli::*, cli_types::*};
use crate::{
cli::*,
cli_types::*,
directories::{InputsDirectory, SourceDirectory},
errors::{CLIError, NewError},
files::{Gitignore, MainFile, Manifest},
};
use clap::ArgMatches;
use std::env::current_dir;
use std::fs;
use std::{env::current_dir, fs};
#[derive(Debug)]
pub struct NewCommand;
@ -14,7 +16,6 @@ impl CLI for NewCommand {
type Options = Option<String>;
type Output = ();
const NAME: NameType = "new";
const ABOUT: AboutType = "Create a new Leo package in a new directory";
const ARGUMENTS: &'static [ArgumentType] = &[
// (name, description, required, index)
@ -26,6 +27,7 @@ impl CLI for NewCommand {
),
];
const FLAGS: &'static [FlagType] = &[];
const NAME: NameType = "new";
const OPTIONS: &'static [OptionType] = &[];
const SUBCOMMANDS: &'static [SubCommandType] = &[];

View File

@ -1,16 +1,17 @@
use crate::commands::SetupCommand;
use crate::errors::CLIError;
use crate::files::{Manifest, ProofFile};
use crate::{cli::*, cli_types::*};
use crate::{
cli::*,
cli_types::*,
commands::SetupCommand,
errors::CLIError,
files::{Manifest, ProofFile},
};
use snarkos_algorithms::snark::{create_random_proof, Proof};
use snarkos_curves::bls12_377::Bls12_377;
use clap::ArgMatches;
use rand::thread_rng;
use std::convert::TryFrom;
use std::env::current_dir;
use std::time::Instant;
use std::{convert::TryFrom, env::current_dir, time::Instant};
#[derive(Debug)]
pub struct ProveCommand;
@ -19,10 +20,10 @@ impl CLI for ProveCommand {
type Options = ();
type Output = Proof<Bls12_377>;
const NAME: NameType = "prove";
const ABOUT: AboutType = "Run the program and produce a proof";
const ARGUMENTS: &'static [ArgumentType] = &[];
const FLAGS: &'static [FlagType] = &[];
const NAME: NameType = "prove";
const OPTIONS: &'static [OptionType] = &[];
const SUBCOMMANDS: &'static [SubCommandType] = &[];
@ -45,10 +46,7 @@ impl CLI for ProveCommand {
let rng = &mut thread_rng();
let program_proof = create_random_proof(program, &parameters, rng).unwrap();
log::info!(
"Prover completed in {:?} milliseconds",
start.elapsed().as_millis()
);
log::info!("Prover completed in {:?} milliseconds", start.elapsed().as_millis());
// Write the proof file to the outputs directory
let mut proof = vec![];

View File

@ -1,11 +1,7 @@
use crate::commands::BuildCommand;
use crate::errors::CLIError;
use crate::files::Manifest;
use crate::{cli::*, cli_types::*};
use crate::{cli::*, cli_types::*, commands::BuildCommand, errors::CLIError, files::Manifest};
use clap::ArgMatches;
use std::convert::TryFrom;
use std::env::current_dir;
use std::{convert::TryFrom, env::current_dir};
#[derive(Debug)]
pub struct PublishCommand;
@ -14,10 +10,10 @@ impl CLI for PublishCommand {
type Options = ();
type Output = ();
const NAME: NameType = "publish";
const ABOUT: AboutType = "Publish the current package to the package manager (*)";
const ARGUMENTS: &'static [ArgumentType] = &[];
const FLAGS: &'static [FlagType] = &[];
const NAME: NameType = "publish";
const OPTIONS: &'static [OptionType] = &[];
const SUBCOMMANDS: &'static [SubCommandType] = &[];

View File

@ -1,6 +1,9 @@
use crate::commands::{ProveCommand, SetupCommand};
use crate::errors::CLIError;
use crate::{cli::*, cli_types::*};
use crate::{
cli::*,
cli_types::*,
commands::{ProveCommand, SetupCommand},
errors::CLIError,
};
use snarkos_algorithms::snark::verify_proof;
@ -14,10 +17,10 @@ impl CLI for RunCommand {
type Options = ();
type Output = ();
const NAME: NameType = "run";
const ABOUT: AboutType = "Run a program with inputs";
const ARGUMENTS: &'static [ArgumentType] = &[];
const FLAGS: &'static [FlagType] = &[];
const NAME: NameType = "run";
const OPTIONS: &'static [OptionType] = &[];
const SUBCOMMANDS: &'static [SubCommandType] = &[];
@ -42,10 +45,7 @@ impl CLI for RunCommand {
verifying += start.elapsed();
println!(" ");
println!(
" Verifier time : {:?} milliseconds",
verifying.as_millis()
);
println!(" Verifier time : {:?} milliseconds", verifying.as_millis());
println!(" Verifier output : {}", is_success);
println!(" ");

View File

@ -1,20 +1,19 @@
use crate::commands::BuildCommand;
use crate::errors::{CLIError, VerificationKeyFileError};
use crate::files::{Manifest, ProvingKeyFile, VerificationKeyFile};
use crate::{cli::*, cli_types::*};
use crate::{
cli::*,
cli_types::*,
commands::BuildCommand,
errors::{CLIError, VerificationKeyFileError},
files::{Manifest, ProvingKeyFile, VerificationKeyFile},
};
use leo_compiler::{compiler::Compiler, group::edwards_bls12::EdwardsGroupType};
use snarkos_algorithms::snark::{
generate_random_parameters, prepare_verifying_key, Parameters, PreparedVerifyingKey,
};
use snarkos_algorithms::snark::{generate_random_parameters, prepare_verifying_key, Parameters, PreparedVerifyingKey};
use snarkos_curves::{bls12_377::Bls12_377, edwards_bls12::Fq};
use snarkos_utilities::bytes::ToBytes;
use clap::ArgMatches;
use rand::thread_rng;
use std::convert::TryFrom;
use std::env::current_dir;
use std::time::Instant;
use std::{convert::TryFrom, env::current_dir, time::Instant};
#[derive(Debug)]
pub struct SetupCommand;
@ -27,10 +26,10 @@ impl CLI for SetupCommand {
PreparedVerifyingKey<Bls12_377>,
);
const NAME: NameType = "setup";
const ABOUT: AboutType = "Run a program setup";
const ARGUMENTS: &'static [ArgumentType] = &[];
const FLAGS: &'static [FlagType] = &[];
const NAME: NameType = "setup";
const OPTIONS: &'static [OptionType] = &[];
const SUBCOMMANDS: &'static [SubCommandType] = &[];
@ -58,15 +57,11 @@ impl CLI for SetupCommand {
// Run the program setup operation
let rng = &mut thread_rng();
let parameters =
generate_random_parameters::<Bls12_377, _, _>(program.clone(), rng).unwrap();
let parameters = generate_random_parameters::<Bls12_377, _, _>(program.clone(), rng).unwrap();
let prepared_verifying_key = prepare_verifying_key::<Bls12_377>(&parameters.vk);
// End the timer
log::info!(
"Setup completed in {:?} milliseconds",
start.elapsed().as_millis()
);
log::info!("Setup completed in {:?} milliseconds", start.elapsed().as_millis());
// TODO (howardwu): Convert parameters to a 'proving key' struct for serialization.
// Write the proving key file to the outputs directory
@ -95,10 +90,7 @@ impl CLI for SetupCommand {
prepared_verifying_key.write(&mut verification_key)?;
// Check that the constructed prepared verification key matches the stored verification key
let compare: Vec<(u8, u8)> = verification_key
.into_iter()
.zip(stored_vk.into_iter())
.collect();
let compare: Vec<(u8, u8)> = verification_key.into_iter().zip(stored_vk.into_iter()).collect();
for (a, b) in compare {
if a != b {
return Err(VerificationKeyFileError::IncorrectVerificationKey.into());

View File

@ -1,16 +1,17 @@
use crate::directories::source::SOURCE_DIRECTORY_NAME;
use crate::errors::{CLIError, TestError};
use crate::files::{MainFile, Manifest, MAIN_FILE_NAME};
use crate::{cli::*, cli_types::*};
use leo_compiler::compiler::Compiler;
use leo_compiler::group::edwards_bls12::EdwardsGroupType;
use crate::{
cli::*,
cli_types::*,
directories::source::SOURCE_DIRECTORY_NAME,
errors::{CLIError, TestError},
files::{MainFile, Manifest, MAIN_FILE_NAME},
};
use leo_compiler::{compiler::Compiler, group::edwards_bls12::EdwardsGroupType};
use snarkos_curves::edwards_bls12::Fq;
use snarkos_models::gadgets::r1cs::TestConstraintSystem;
use clap::ArgMatches;
use std::convert::TryFrom;
use std::env::current_dir;
use std::{convert::TryFrom, env::current_dir};
#[derive(Debug)]
pub struct TestCommand;
@ -19,10 +20,10 @@ impl CLI for TestCommand {
type Options = ();
type Output = ();
const NAME: NameType = "test";
const ABOUT: AboutType = "Compile and run all tests in the current package";
const ARGUMENTS: &'static [ArgumentType] = &[];
const FLAGS: &'static [FlagType] = &[];
const NAME: NameType = "test";
const OPTIONS: &'static [OptionType] = &[];
const SUBCOMMANDS: &'static [SubCommandType] = &[];
@ -47,9 +48,7 @@ impl CLI for TestCommand {
// Verify the main file exists
if !MainFile::exists_at(&package_path) {
return Err(
TestError::MainFileDoesNotExist(package_path.as_os_str().to_owned()).into(),
);
return Err(TestError::MainFileDoesNotExist(package_path.as_os_str().to_owned()).into());
}
// Construct the path to the main file in the source directory
@ -58,8 +57,7 @@ impl CLI for TestCommand {
main_file_path.push(MAIN_FILE_NAME);
// Compute the current program checksum
let program =
Compiler::<Fq, EdwardsGroupType>::init(package_name.clone(), main_file_path.clone())?;
let program = Compiler::<Fq, EdwardsGroupType>::init(package_name.clone(), main_file_path.clone())?;
// Generate the program on the constraint system and verify correctness
{

View File

@ -1,11 +1,7 @@
use crate::commands::BuildCommand;
use crate::errors::CLIError;
use crate::files::Manifest;
use crate::{cli::*, cli_types::*};
use crate::{cli::*, cli_types::*, commands::BuildCommand, errors::CLIError, files::Manifest};
use clap::ArgMatches;
use std::convert::TryFrom;
use std::env::current_dir;
use std::{convert::TryFrom, env::current_dir};
#[derive(Debug)]
pub struct UnloadCommand;
@ -14,10 +10,10 @@ impl CLI for UnloadCommand {
type Options = ();
type Output = ();
const NAME: NameType = "unload";
const ABOUT: AboutType = "Uninstall a package from the current package (*)";
const ARGUMENTS: &'static [ArgumentType] = &[];
const FLAGS: &'static [FlagType] = &[];
const NAME: NameType = "unload";
const OPTIONS: &'static [OptionType] = &[];
const SUBCOMMANDS: &'static [SubCommandType] = &[];

View File

@ -1,7 +1,6 @@
use crate::errors::InputsDirectoryError;
use std::fs;
use std::path::PathBuf;
use std::{fs, path::PathBuf};
pub(crate) static INPUTS_DIRECTORY_NAME: &str = "inputs/";
@ -32,9 +31,9 @@ impl InputsDirectory {
let file_path = file_entry.path();
// Verify that the entry is structured as a valid file
let file_type = file_entry.file_type().map_err(|error| {
InputsDirectoryError::GettingFileType(file_path.as_os_str().to_owned(), error)
})?;
let file_type = file_entry
.file_type()
.map_err(|error| InputsDirectoryError::GettingFileType(file_path.as_os_str().to_owned(), error))?;
if !file_type.is_file() {
return Err(InputsDirectoryError::InvalidFileType(
file_path.as_os_str().to_owned(),
@ -43,9 +42,9 @@ impl InputsDirectory {
}
// Verify that the file has the default file extension
let file_extension = file_path.extension().ok_or_else(|| {
InputsDirectoryError::GettingFileExtension(file_path.as_os_str().to_owned())
})?;
let file_extension = file_path
.extension()
.ok_or_else(|| InputsDirectoryError::GettingFileExtension(file_path.as_os_str().to_owned()))?;
if file_extension != INPUTS_FILE_EXTENSION {
return Err(InputsDirectoryError::InvalidFileExtension(
file_path.as_os_str().to_owned(),

View File

@ -1,7 +1,6 @@
use crate::errors::OutputsDirectoryError;
use std::fs;
use std::path::PathBuf;
use std::{fs, path::PathBuf};
pub(crate) static OUTPUTS_DIRECTORY_NAME: &str = "outputs/";

View File

@ -1,7 +1,6 @@
use crate::errors::SourceDirectoryError;
use std::fs;
use std::path::PathBuf;
use std::{fs, path::PathBuf};
pub(crate) static SOURCE_DIRECTORY_NAME: &str = "src/";
@ -32,9 +31,9 @@ impl SourceDirectory {
let file_path = file_entry.path();
// Verify that the entry is structured as a valid file
let file_type = file_entry.file_type().map_err(|error| {
SourceDirectoryError::GettingFileType(file_path.as_os_str().to_owned(), error)
})?;
let file_type = file_entry
.file_type()
.map_err(|error| SourceDirectoryError::GettingFileType(file_path.as_os_str().to_owned(), error))?;
if !file_type.is_file() {
return Err(SourceDirectoryError::InvalidFileType(
file_path.as_os_str().to_owned(),
@ -43,9 +42,9 @@ impl SourceDirectory {
}
// Verify that the file has the default file extension
let file_extension = file_path.extension().ok_or_else(|| {
SourceDirectoryError::GettingFileExtension(file_path.as_os_str().to_owned())
})?;
let file_extension = file_path
.extension()
.ok_or_else(|| SourceDirectoryError::GettingFileExtension(file_path.as_os_str().to_owned()))?;
if file_extension != SOURCE_FILE_EXTENSION {
return Err(SourceDirectoryError::InvalidFileExtension(
file_path.as_os_str().to_owned(),

View File

@ -1,7 +1,6 @@
use crate::errors::ManifestError;
use std::ffi::OsString;
use std::io;
use std::{ffi::OsString, io};
#[derive(Debug, Error)]
pub enum InitError {

View File

@ -1,7 +1,6 @@
use crate::errors::ManifestError;
use std::ffi::OsString;
use std::io;
use std::{ffi::OsString, io};
#[derive(Debug, Error)]
pub enum NewError {

View File

@ -1,5 +1,4 @@
use std::io;
use std::path::PathBuf;
use std::{io, path::PathBuf};
#[derive(Debug, Error)]
pub enum ChecksumFileError {

View File

@ -1,5 +1,4 @@
use std::io;
use std::path::PathBuf;
use std::{io, path::PathBuf};
#[derive(Debug, Error)]
pub enum ProofFileError {

View File

@ -1,5 +1,4 @@
use std::io;
use std::path::PathBuf;
use std::{io, path::PathBuf};
#[derive(Debug, Error)]
pub enum ProvingKeyFileError {

View File

@ -1,5 +1,4 @@
use std::io;
use std::path::PathBuf;
use std::{io, path::PathBuf};
#[derive(Debug, Error)]
pub enum VerificationKeyFileError {

View File

@ -1,12 +1,13 @@
//! The build checksum file.
use crate::directories::outputs::OUTPUTS_DIRECTORY_NAME;
use crate::errors::ChecksumFileError;
use crate::{directories::outputs::OUTPUTS_DIRECTORY_NAME, errors::ChecksumFileError};
use serde::Deserialize;
use std::fs::{self, File};
use std::io::Write;
use std::path::PathBuf;
use std::{
fs::{self, File},
io::Write,
path::PathBuf,
};
pub static CHECKSUM_FILE_EXTENSION: &str = ".leo.checksum";
@ -31,10 +32,7 @@ impl ChecksumFile {
pub fn read_from(&self, path: &PathBuf) -> Result<String, ChecksumFileError> {
let path = self.setup_file_path(path);
Ok(
fs::read_to_string(&path)
.map_err(|_| ChecksumFileError::FileReadError(path.clone()))?,
)
Ok(fs::read_to_string(&path).map_err(|_| ChecksumFileError::FileReadError(path.clone()))?)
}
/// Writes the given checksum to a file.

View File

@ -3,9 +3,7 @@
use crate::errors::GitignoreError;
use serde::Deserialize;
use std::fs::File;
use std::io::Write;
use std::path::PathBuf;
use std::{fs::File, io::Write, path::PathBuf};
pub static GITIGNORE_FILE_NAME: &str = ".gitignore";

View File

@ -1,12 +1,9 @@
//! The `main.leo` file.
use crate::directories::source::SOURCE_DIRECTORY_NAME;
use crate::errors::MainFileError;
use crate::{directories::source::SOURCE_DIRECTORY_NAME, errors::MainFileError};
use serde::Deserialize;
use std::fs::File;
use std::io::Write;
use std::path::PathBuf;
use std::{fs::File, io::Write, path::PathBuf};
pub static MAIN_FILE_NAME: &str = "main.leo";

View File

@ -1,11 +1,12 @@
use crate::errors::ManifestError;
use serde::Deserialize;
use std::convert::TryFrom;
use std::fs::File;
use std::io::Read;
use std::io::Write;
use std::path::PathBuf;
use std::{
convert::TryFrom,
fs::File,
io::{Read, Write},
path::PathBuf,
};
pub static MANIFEST_FILE_NAME: &str = "Leo.toml";
@ -48,8 +49,7 @@ impl Manifest {
path.push(PathBuf::from(MANIFEST_FILE_NAME));
}
let mut file = File::create(&path)
.map_err(|error| ManifestError::Creating(MANIFEST_FILE_NAME, error))?;
let mut file = File::create(&path).map_err(|error| ManifestError::Creating(MANIFEST_FILE_NAME, error))?;
file.write_all(self.template().as_bytes())
.map_err(|error| ManifestError::Writing(MANIFEST_FILE_NAME, error))
}
@ -74,8 +74,7 @@ impl TryFrom<&PathBuf> for Manifest {
path.push(PathBuf::from(MANIFEST_FILE_NAME));
}
let mut file =
File::open(path).map_err(|error| ManifestError::Opening(MANIFEST_FILE_NAME, error))?;
let mut file = File::open(path).map_err(|error| ManifestError::Opening(MANIFEST_FILE_NAME, error))?;
let size = file
.metadata()
.map_err(|error| ManifestError::Metadata(MANIFEST_FILE_NAME, error))?
@ -85,7 +84,6 @@ impl TryFrom<&PathBuf> for Manifest {
file.read_to_string(&mut buffer)
.map_err(|error| ManifestError::Reading(MANIFEST_FILE_NAME, error))?;
Ok(toml::from_str(&buffer)
.map_err(|error| ManifestError::Parsing(MANIFEST_FILE_NAME, error))?)
Ok(toml::from_str(&buffer).map_err(|error| ManifestError::Parsing(MANIFEST_FILE_NAME, error))?)
}
}

View File

@ -1,12 +1,13 @@
//! The proof file.
use crate::directories::outputs::OUTPUTS_DIRECTORY_NAME;
use crate::errors::ProofFileError;
use crate::{directories::outputs::OUTPUTS_DIRECTORY_NAME, errors::ProofFileError};
use serde::Deserialize;
use std::fs::{self, File};
use std::io::Write;
use std::path::PathBuf;
use std::{
fs::{self, File},
io::Write,
path::PathBuf,
};
pub static PROOF_FILE_EXTENSION: &str = ".leo.proof";
@ -31,8 +32,7 @@ impl ProofFile {
pub fn read_from(&self, path: &PathBuf) -> Result<String, ProofFileError> {
let path = self.setup_file_path(path);
let proof =
fs::read_to_string(&path).map_err(|_| ProofFileError::FileReadError(path.clone()))?;
let proof = fs::read_to_string(&path).map_err(|_| ProofFileError::FileReadError(path.clone()))?;
Ok(proof)
}
@ -54,10 +54,7 @@ impl ProofFile {
if !path.ends_with(OUTPUTS_DIRECTORY_NAME) {
path.push(PathBuf::from(OUTPUTS_DIRECTORY_NAME));
}
path.push(PathBuf::from(format!(
"{}{}",
self.package_name, PROOF_FILE_EXTENSION
)));
path.push(PathBuf::from(format!("{}{}", self.package_name, PROOF_FILE_EXTENSION)));
}
path
}

View File

@ -1,12 +1,13 @@
//! The proving key file.
use crate::directories::outputs::OUTPUTS_DIRECTORY_NAME;
use crate::errors::ProvingKeyFileError;
use crate::{directories::outputs::OUTPUTS_DIRECTORY_NAME, errors::ProvingKeyFileError};
use serde::Deserialize;
use std::fs::{self, File};
use std::io::Write;
use std::path::PathBuf;
use std::{
fs::{self, File},
io::Write,
path::PathBuf,
};
pub static PROVING_KEY_FILE_EXTENSION: &str = ".leo.pk";

Some files were not shown because too many files have changed in this diff Show More