mirror of
https://github.com/ProvableHQ/leo.git
synced 2025-01-05 09:16:21 +03:00
Merge pull request #384 from ljedrz/clippy_compliance
Clippy compliance, part 1/2
This commit is contained in:
commit
6ede1f72eb
@ -14,6 +14,8 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#![allow(clippy::module_inception)]
|
||||||
|
|
||||||
pub mod access;
|
pub mod access;
|
||||||
pub use access::*;
|
pub use access::*;
|
||||||
|
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#![allow(clippy::module_inception)]
|
||||||
|
|
||||||
pub mod annotations;
|
pub mod annotations;
|
||||||
pub use annotations::*;
|
pub use annotations::*;
|
||||||
|
|
||||||
|
@ -39,20 +39,17 @@ pub enum ParserError {
|
|||||||
|
|
||||||
impl ParserError {
|
impl ParserError {
|
||||||
pub fn set_path(&mut self, path: PathBuf) {
|
pub fn set_path(&mut self, path: PathBuf) {
|
||||||
match self {
|
if let ParserError::SyntaxError(error) = self {
|
||||||
ParserError::SyntaxError(error) => {
|
let new_error: Error<Rule> = match error {
|
||||||
let new_error: Error<Rule> = match error {
|
SyntaxError::Error(error) => {
|
||||||
SyntaxError::Error(error) => {
|
let new_error = error.clone();
|
||||||
let new_error = error.clone();
|
new_error.with_path(path.to_str().unwrap())
|
||||||
new_error.with_path(path.to_str().unwrap())
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
|
|
||||||
tracing::error!("{}", new_error);
|
tracing::error!("{}", new_error);
|
||||||
|
|
||||||
*error = SyntaxError::Error(new_error);
|
*error = SyntaxError::Error(new_error);
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#![allow(clippy::module_inception)]
|
||||||
|
|
||||||
pub mod function_input;
|
pub mod function_input;
|
||||||
pub use function_input::*;
|
pub use function_input::*;
|
||||||
|
|
||||||
|
@ -39,11 +39,11 @@ pub struct ConditionalStatement<'ast> {
|
|||||||
|
|
||||||
impl<'ast> fmt::Display for ConditionalStatement<'ast> {
|
impl<'ast> fmt::Display for ConditionalStatement<'ast> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "if ({}) {{\n", self.condition)?;
|
writeln!(f, "if ({}) {{", self.condition)?;
|
||||||
write!(f, "\t{:#?}\n", self.statements)?;
|
writeln!(f, "\t{:#?}", self.statements)?;
|
||||||
self.next
|
self.next
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|n_or_e| write!(f, "}} {}", n_or_e))
|
.map(|n_or_e| write!(f, "}} {}", n_or_e))
|
||||||
.unwrap_or(write!(f, "}}"))
|
.unwrap_or_else(|| write!(f, "}}"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,6 +135,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Parses the Leo program file, constructs a syntax tree, and generates a program.
|
/// Parses the Leo program file, constructs a syntax tree, and generates a program.
|
||||||
|
#[allow(deprecated)]
|
||||||
pub(crate) fn parse_program(&mut self) -> Result<(), CompilerError> {
|
pub(crate) fn parse_program(&mut self) -> Result<(), CompilerError> {
|
||||||
// Use the parser to construct the abstract syntax tree.
|
// Use the parser to construct the abstract syntax tree.
|
||||||
let program_string = LeoAst::load_file(&self.main_file_path)?;
|
let program_string = LeoAst::load_file(&self.main_file_path)?;
|
||||||
|
@ -53,9 +53,9 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
// Unwrap assertion value and handle errors
|
// Unwrap assertion value and handle errors
|
||||||
let result_option = match assert_expression {
|
let result_option = match assert_expression {
|
||||||
ConstrainedValue::Boolean(boolean) => boolean.get_value(),
|
ConstrainedValue::Boolean(boolean) => boolean.get_value(),
|
||||||
_ => return Err(ConsoleError::assertion_must_be_boolean(expression_string, span.clone())),
|
_ => return Err(ConsoleError::assertion_must_be_boolean(expression_string, span)),
|
||||||
};
|
};
|
||||||
let result_bool = result_option.ok_or(ConsoleError::assertion_depends_on_input(span.clone()))?;
|
let result_bool = result_option.ok_or_else(|| ConsoleError::assertion_depends_on_input(span.clone()))?;
|
||||||
|
|
||||||
if !result_bool {
|
if !result_bool {
|
||||||
return Err(ConsoleError::assertion_failed(expression_string, span));
|
return Err(ConsoleError::assertion_failed(expression_string, span));
|
||||||
|
@ -37,16 +37,16 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
return Err(ConsoleError::length(
|
return Err(ConsoleError::length(
|
||||||
formatted.containers.len(),
|
formatted.containers.len(),
|
||||||
formatted.parameters.len(),
|
formatted.parameters.len(),
|
||||||
formatted.span.clone(),
|
formatted.span,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trim starting double quote `"`
|
// Trim starting double quote `"`
|
||||||
let mut string = formatted.string.as_str();
|
let mut string = formatted.string.as_str();
|
||||||
string = string.trim_start_matches("\"");
|
string = string.trim_start_matches('\"');
|
||||||
|
|
||||||
// Trim everything after the ending double quote `"`
|
// Trim everything after the ending double quote `"`
|
||||||
let parts: Vec<&str> = string.split("\"").collect();
|
let parts: Vec<&str> = string.split('\"').collect();
|
||||||
string = parts[0];
|
string = parts[0];
|
||||||
|
|
||||||
// Insert the parameter for each container `{}`
|
// Insert the parameter for each container `{}`
|
||||||
|
@ -32,7 +32,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
mutable: bool,
|
mutable: bool,
|
||||||
identifier: Identifier,
|
identifier: Identifier,
|
||||||
mut value: ConstrainedValue<F, G>,
|
mut value: ConstrainedValue<F, G>,
|
||||||
) -> () {
|
) {
|
||||||
// Store with given mutability
|
// Store with given mutability
|
||||||
if mutable {
|
if mutable {
|
||||||
value = ConstrainedValue::Mutable(Box::new(value));
|
value = ConstrainedValue::Mutable(Box::new(value));
|
||||||
|
@ -50,7 +50,8 @@ impl ConsoleError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn assertion_depends_on_input(span: Span) -> Self {
|
pub fn assertion_depends_on_input(span: Span) -> Self {
|
||||||
let message = format!("console.assert() failed to evaluate. This error is caused by empty input file values");
|
let message =
|
||||||
|
"console.assert() failed to evaluate. This error is caused by empty input file values".to_string();
|
||||||
|
|
||||||
Self::new_from_span(message, span)
|
Self::new_from_span(message, span)
|
||||||
}
|
}
|
||||||
|
@ -146,7 +146,7 @@ impl ExpressionError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn self_keyword(span: Span) -> Self {
|
pub fn self_keyword(span: Span) -> Self {
|
||||||
let message = format!("cannot call keyword `Self` outside of a circuit function");
|
let message = "cannot call keyword `Self` outside of a circuit function".to_string();
|
||||||
|
|
||||||
Self::new_from_span(message, span)
|
Self::new_from_span(message, span)
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ impl ImportError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn convert_os_string(span: Span) -> Self {
|
pub fn convert_os_string(span: Span) -> Self {
|
||||||
let message = format!("failed to convert file string name, maybe an illegal character?");
|
let message = "failed to convert file string name, maybe an illegal character?".to_string();
|
||||||
|
|
||||||
Self::new_from_span(message, span)
|
Self::new_from_span(message, span)
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ impl OutputBytesError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn not_enough_registers(span: Span) -> Self {
|
pub fn not_enough_registers(span: Span) -> Self {
|
||||||
let message = format!("number of input registers must be greater than or equal to output registers");
|
let message = "number of input registers must be greater than or equal to output registers".to_string();
|
||||||
|
|
||||||
Self::new_from_span(message, span)
|
Self::new_from_span(message, span)
|
||||||
}
|
}
|
||||||
|
@ -67,13 +67,13 @@ impl StatementError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn array_assign_index(span: Span) -> Self {
|
pub fn array_assign_index(span: Span) -> Self {
|
||||||
let message = format!("Cannot assign single index to array of values");
|
let message = "Cannot assign single index to array of values".to_string();
|
||||||
|
|
||||||
Self::new_from_span(message, span)
|
Self::new_from_span(message, span)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn array_assign_range(span: Span) -> Self {
|
pub fn array_assign_range(span: Span) -> Self {
|
||||||
let message = format!("Cannot assign range of array values to single value");
|
let message = "Cannot assign range of array values to single value".to_string();
|
||||||
|
|
||||||
Self::new_from_span(message, span)
|
Self::new_from_span(message, span)
|
||||||
}
|
}
|
||||||
@ -145,7 +145,7 @@ impl StatementError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn tuple_assign_index(span: Span) -> Self {
|
pub fn tuple_assign_index(span: Span) -> Self {
|
||||||
let message = format!("Cannot assign single index to tuple of values");
|
let message = "Cannot assign single index to tuple of values".to_string();
|
||||||
|
|
||||||
Self::new_from_span(message, span)
|
Self::new_from_span(message, span)
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ impl AddressError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn missing_address(span: Span) -> Self {
|
pub fn missing_address(span: Span) -> Self {
|
||||||
let message = format!("expected address input not found");
|
let message = "expected address input not found".to_string();
|
||||||
|
|
||||||
Self::new_from_span(message, span)
|
Self::new_from_span(message, span)
|
||||||
}
|
}
|
||||||
|
@ -88,13 +88,13 @@ impl GroupError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn x_recover(span: Span) -> Self {
|
pub fn x_recover(span: Span) -> Self {
|
||||||
let message = format!("could not recover group element from x coordinate");
|
let message = "could not recover group element from x coordinate".to_string();
|
||||||
|
|
||||||
Self::new_from_span(message, span)
|
Self::new_from_span(message, span)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn y_recover(span: Span) -> Self {
|
pub fn y_recover(span: Span) -> Self {
|
||||||
let message = format!("could not recover group element from y coordinate");
|
let message = "could not recover group element from y coordinate".to_string();
|
||||||
|
|
||||||
Self::new_from_span(message, span)
|
Self::new_from_span(message, span)
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ impl IntegerError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn negate_operation(span: Span) -> Self {
|
pub fn negate_operation(span: Span) -> Self {
|
||||||
let message = format!("integer negation can only be enforced on signed integers");
|
let message = "integer negation can only be enforced on signed integers".to_string();
|
||||||
|
|
||||||
Self::new_from_span(message, span)
|
Self::new_from_span(message, span)
|
||||||
}
|
}
|
||||||
@ -83,9 +83,9 @@ impl IntegerError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn invalid_index(span: Span) -> Self {
|
pub fn invalid_index(span: Span) -> Self {
|
||||||
let message = format!(
|
let message =
|
||||||
"index must be a constant value unsigned integer. allocated indices produce a circuit of unknown size"
|
"index must be a constant value unsigned integer. allocated indices produce a circuit of unknown size"
|
||||||
);
|
.to_string();
|
||||||
|
|
||||||
Self::new_from_span(message, span)
|
Self::new_from_span(message, span)
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ impl ValueError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn implicit_group(span: Span) -> Self {
|
pub fn implicit_group(span: Span) -> Self {
|
||||||
let message = format!("group coordinates should be in (x, y)group format");
|
let message = "group coordinates should be in (x, y)group format".to_string();
|
||||||
|
|
||||||
Self::new_from_span(message, span)
|
Self::new_from_span(message, span)
|
||||||
}
|
}
|
||||||
|
@ -45,11 +45,9 @@ pub fn enforce_div<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<
|
|||||||
let val_2 = ConstrainedValue::from_other(string, &val_1, span.clone())?;
|
let val_2 = ConstrainedValue::from_other(string, &val_1, span.clone())?;
|
||||||
enforce_div(cs, val_1, val_2, span)
|
enforce_div(cs, val_1, val_2, span)
|
||||||
}
|
}
|
||||||
(val_1, val_2) => {
|
(val_1, val_2) => Err(ExpressionError::incompatible_types(
|
||||||
return Err(ExpressionError::incompatible_types(
|
format!("{} / {}", val_1, val_2,),
|
||||||
format!("{} / {}", val_1, val_2,),
|
span,
|
||||||
span,
|
)),
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,11 +45,9 @@ pub fn enforce_mul<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<
|
|||||||
let val_2 = ConstrainedValue::from_other(string, &val_1, span.clone())?;
|
let val_2 = ConstrainedValue::from_other(string, &val_1, span.clone())?;
|
||||||
enforce_mul(cs, val_1, val_2, span)
|
enforce_mul(cs, val_1, val_2, span)
|
||||||
}
|
}
|
||||||
(val_1, val_2) => {
|
(val_1, val_2) => Err(ExpressionError::incompatible_types(
|
||||||
return Err(ExpressionError::incompatible_types(
|
format!("{} * {}", val_1, val_2),
|
||||||
format!("{} * {}", val_1, val_2),
|
span,
|
||||||
span,
|
)),
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ use snarkos_models::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn enforce_array_access<CS: ConstraintSystem<F>>(
|
pub fn enforce_array_access<CS: ConstraintSystem<F>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
cs: &mut CS,
|
cs: &mut CS,
|
||||||
@ -56,9 +57,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
None => 0usize, // Array slice starts at index 0
|
None => 0usize, // Array slice starts at index 0
|
||||||
};
|
};
|
||||||
let to_resolved = match to {
|
let to_resolved = match to {
|
||||||
Some(to_index) => {
|
Some(to_index) => self.enforce_index(cs, file_scope, function_scope, to_index, span)?,
|
||||||
self.enforce_index(cs, file_scope.clone(), function_scope.clone(), to_index, span.clone())?
|
|
||||||
}
|
|
||||||
None => array.len(), // Array slice ends at array length
|
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()))
|
||||||
|
@ -37,7 +37,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
file_scope: String,
|
file_scope: String,
|
||||||
function_scope: String,
|
function_scope: String,
|
||||||
mut expected_type: Option<Type>,
|
mut expected_type: Option<Type>,
|
||||||
array: Vec<Box<SpreadOrExpression>>,
|
array: Vec<SpreadOrExpression>,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||||
// Check explicit array type dimension if given
|
// Check explicit array type dimension if given
|
||||||
@ -47,12 +47,12 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
match type_ {
|
match type_ {
|
||||||
Type::Array(ref type_, ref dimensions) => {
|
Type::Array(ref type_, ref dimensions) => {
|
||||||
let number = match dimensions.first() {
|
let number = match dimensions.first() {
|
||||||
Some(number) => number.clone(),
|
Some(number) => *number,
|
||||||
None => return Err(ExpressionError::unexpected_array(type_.to_string(), span)),
|
None => return Err(ExpressionError::unexpected_array(type_.to_string(), span)),
|
||||||
};
|
};
|
||||||
|
|
||||||
expected_dimensions.push(number);
|
expected_dimensions.push(number);
|
||||||
expected_type = Some(type_.outer_dimension(dimensions).clone());
|
expected_type = Some(type_.outer_dimension(dimensions));
|
||||||
}
|
}
|
||||||
ref type_ => {
|
ref type_ => {
|
||||||
return Err(ExpressionError::unexpected_array(type_.to_string(), span));
|
return Err(ExpressionError::unexpected_array(type_.to_string(), span));
|
||||||
@ -62,7 +62,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
|
|
||||||
let mut result = vec![];
|
let mut result = vec![];
|
||||||
for element in array.into_iter() {
|
for element in array.into_iter() {
|
||||||
match *element {
|
match element {
|
||||||
SpreadOrExpression::Spread(spread) => match spread {
|
SpreadOrExpression::Spread(spread) => match spread {
|
||||||
Expression::Identifier(identifier) => {
|
Expression::Identifier(identifier) => {
|
||||||
let array_name = new_scope(function_scope.clone(), identifier.to_string());
|
let array_name = new_scope(function_scope.clone(), identifier.to_string());
|
||||||
@ -89,14 +89,12 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check expected_dimensions if given
|
// Check expected_dimensions if given
|
||||||
if !expected_dimensions.is_empty() {
|
if !expected_dimensions.is_empty() && expected_dimensions[expected_dimensions.len() - 1] != result.len() {
|
||||||
if expected_dimensions[expected_dimensions.len() - 1] != result.len() {
|
return Err(ExpressionError::invalid_length(
|
||||||
return Err(ExpressionError::invalid_length(
|
expected_dimensions[expected_dimensions.len() - 1],
|
||||||
expected_dimensions[expected_dimensions.len() - 1],
|
result.len(),
|
||||||
result.len(),
|
span,
|
||||||
span,
|
));
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ConstrainedValue::Array(result))
|
Ok(ConstrainedValue::Array(result))
|
||||||
|
@ -34,15 +34,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
span: Span,
|
span: Span,
|
||||||
) -> Result<usize, ExpressionError> {
|
) -> Result<usize, ExpressionError> {
|
||||||
let expected_type = Some(Type::IntegerType(IntegerType::U32));
|
let expected_type = Some(Type::IntegerType(IntegerType::U32));
|
||||||
match self.enforce_operand(
|
match self.enforce_operand(cs, file_scope, function_scope, expected_type, index, span.clone())? {
|
||||||
cs,
|
ConstrainedValue::Integer(number) => Ok(number.to_usize(span)?),
|
||||||
file_scope.clone(),
|
|
||||||
function_scope.clone(),
|
|
||||||
expected_type,
|
|
||||||
index,
|
|
||||||
span.clone(),
|
|
||||||
)? {
|
|
||||||
ConstrainedValue::Integer(number) => Ok(number.to_usize(span.clone())?),
|
|
||||||
value => Err(ExpressionError::invalid_index(value.to_string(), span)),
|
value => Err(ExpressionError::invalid_index(value.to_string(), span)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,10 @@ use snarkos_models::{
|
|||||||
gadgets::r1cs::ConstraintSystem,
|
gadgets::r1cs::ConstraintSystem,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type ConstrainedValuePair<T, U> = (ConstrainedValue<T, U>, ConstrainedValue<T, U>);
|
||||||
|
|
||||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn enforce_binary_expression<CS: ConstraintSystem<F>>(
|
pub fn enforce_binary_expression<CS: ConstraintSystem<F>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
cs: &mut CS,
|
cs: &mut CS,
|
||||||
@ -34,7 +37,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
left: Expression,
|
left: Expression,
|
||||||
right: Expression,
|
right: Expression,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> Result<(ConstrainedValue<F, G>, ConstrainedValue<F, G>), ExpressionError> {
|
) -> Result<ConstrainedValuePair<F, G>, ExpressionError> {
|
||||||
let mut resolved_left = self.enforce_operand(
|
let mut resolved_left = self.enforce_operand(
|
||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope.clone(),
|
||||||
@ -45,8 +48,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
)?;
|
)?;
|
||||||
let mut resolved_right = self.enforce_operand(
|
let mut resolved_right = self.enforce_operand(
|
||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope,
|
||||||
function_scope.clone(),
|
function_scope,
|
||||||
expected_type.clone(),
|
expected_type.clone(),
|
||||||
right,
|
right,
|
||||||
span.clone(),
|
span.clone(),
|
||||||
|
@ -29,9 +29,10 @@ use snarkos_models::{
|
|||||||
gadgets::r1cs::ConstraintSystem,
|
gadgets::r1cs::ConstraintSystem,
|
||||||
};
|
};
|
||||||
|
|
||||||
static SELF_KEYWORD: &'static str = "self";
|
static SELF_KEYWORD: &str = "self";
|
||||||
|
|
||||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn enforce_circuit_access<CS: ConstraintSystem<F>>(
|
pub fn enforce_circuit_access<CS: ConstraintSystem<F>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
cs: &mut CS,
|
cs: &mut CS,
|
||||||
@ -45,11 +46,11 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
// access a circuit member using the `self` keyword
|
// access a circuit member using the `self` keyword
|
||||||
if let Expression::Identifier(ref identifier) = *circuit_identifier {
|
if let Expression::Identifier(ref identifier) = *circuit_identifier {
|
||||||
if identifier.is_self() {
|
if identifier.is_self() {
|
||||||
let self_file_scope = new_scope(file_scope.clone(), identifier.name.to_string());
|
let self_file_scope = new_scope(file_scope, identifier.name.to_string());
|
||||||
let self_function_scope = new_scope(self_file_scope.clone(), identifier.name.to_string());
|
let self_function_scope = new_scope(self_file_scope.clone(), identifier.name.to_string());
|
||||||
|
|
||||||
let member_value =
|
let member_value =
|
||||||
self.evaluate_identifier(self_file_scope, self_function_scope, None, circuit_member.clone())?;
|
self.evaluate_identifier(self_file_scope, self_function_scope, None, circuit_member)?;
|
||||||
|
|
||||||
return Ok(member_value);
|
return Ok(member_value);
|
||||||
}
|
}
|
||||||
@ -58,9 +59,9 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
let (circuit_name, members) = match self.enforce_operand(
|
let (circuit_name, members) = match self.enforce_operand(
|
||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope.clone(),
|
||||||
function_scope.clone(),
|
function_scope,
|
||||||
expected_type,
|
expected_type,
|
||||||
*circuit_identifier.clone(),
|
*circuit_identifier,
|
||||||
span.clone(),
|
span.clone(),
|
||||||
)? {
|
)? {
|
||||||
ConstrainedValue::CircuitExpression(name, members) => (name, members),
|
ConstrainedValue::CircuitExpression(name, members) => (name, members),
|
||||||
|
@ -40,7 +40,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
span: Span,
|
span: Span,
|
||||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||||
// Circuit definitions are located at the minimum file scope
|
// Circuit definitions are located at the minimum file scope
|
||||||
let scopes: Vec<&str> = file_scope.split("_").collect();
|
let scopes: Vec<&str> = file_scope.split('_').collect();
|
||||||
let mut program_identifier = new_scope(scopes[0].to_string(), identifier.to_string());
|
let mut program_identifier = new_scope(scopes[0].to_string(), identifier.to_string());
|
||||||
|
|
||||||
if identifier.is_self() {
|
if identifier.is_self() {
|
||||||
@ -55,7 +55,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
let circuit_identifier = circuit.circuit_name.clone();
|
let circuit_identifier = circuit.circuit_name.clone();
|
||||||
let mut resolved_members = vec![];
|
let mut resolved_members = vec![];
|
||||||
|
|
||||||
for member in circuit.members.clone().into_iter() {
|
for member in circuit.members.into_iter() {
|
||||||
match member {
|
match member {
|
||||||
CircuitMember::CircuitVariable(is_mutable, identifier, type_) => {
|
CircuitMember::CircuitVariable(is_mutable, identifier, type_) => {
|
||||||
let matched_variable = members
|
let matched_variable = members
|
||||||
@ -98,7 +98,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ok(ConstrainedValue::CircuitExpression(
|
Ok(ConstrainedValue::CircuitExpression(
|
||||||
circuit_identifier.clone(),
|
circuit_identifier,
|
||||||
resolved_members,
|
resolved_members,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ use snarkos_models::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn enforce_circuit_static_access<CS: ConstraintSystem<F>>(
|
pub fn enforce_circuit_static_access<CS: ConstraintSystem<F>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
cs: &mut CS,
|
cs: &mut CS,
|
||||||
@ -36,26 +37,20 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
span: Span,
|
span: Span,
|
||||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||||
// Get defined circuit
|
// Get defined circuit
|
||||||
let circuit = match *circuit_identifier.clone() {
|
let circuit = match *circuit_identifier {
|
||||||
Expression::Identifier(identifier) => {
|
Expression::Identifier(identifier) => {
|
||||||
// Use the "Self" keyword to access a static circuit function
|
// Use the "Self" keyword to access a static circuit function
|
||||||
if identifier.is_self() {
|
if identifier.is_self() {
|
||||||
let circuit = self
|
let circuit = self
|
||||||
.get(&file_scope)
|
.get(&file_scope)
|
||||||
.ok_or(ExpressionError::self_keyword(identifier.span.clone()))?;
|
.ok_or_else(|| ExpressionError::self_keyword(identifier.span))?;
|
||||||
|
|
||||||
circuit.to_owned()
|
circuit.to_owned()
|
||||||
} else {
|
} else {
|
||||||
self.evaluate_identifier(file_scope.clone(), function_scope.clone(), expected_type, identifier)?
|
self.evaluate_identifier(file_scope, function_scope, expected_type, identifier)?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expression => self.enforce_expression(
|
expression => self.enforce_expression(cs, file_scope, function_scope, expected_type, expression)?,
|
||||||
cs,
|
|
||||||
file_scope.clone(),
|
|
||||||
function_scope.clone(),
|
|
||||||
expected_type,
|
|
||||||
expression,
|
|
||||||
)?,
|
|
||||||
}
|
}
|
||||||
.extract_circuit(span.clone())?;
|
.extract_circuit(span.clone())?;
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ use snarkos_models::{
|
|||||||
|
|
||||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||||
/// Enforce ternary conditional expression
|
/// Enforce ternary conditional expression
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn enforce_conditional_expression<CS: ConstraintSystem<F>>(
|
pub fn enforce_conditional_expression<CS: ConstraintSystem<F>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
cs: &mut CS,
|
cs: &mut CS,
|
||||||
@ -57,14 +58,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
span.clone(),
|
span.clone(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let second_value = self.enforce_operand(
|
let second_value = self.enforce_operand(cs, file_scope, function_scope, expected_type, second, span.clone())?;
|
||||||
cs,
|
|
||||||
file_scope.clone(),
|
|
||||||
function_scope.clone(),
|
|
||||||
expected_type,
|
|
||||||
second,
|
|
||||||
span.clone(),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let unique_namespace = cs.ns(|| {
|
let unique_namespace = cs.ns(|| {
|
||||||
format!(
|
format!(
|
||||||
@ -74,6 +68,6 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
ConstrainedValue::conditionally_select(unique_namespace, &conditional_value, &first_value, &second_value)
|
ConstrainedValue::conditionally_select(unique_namespace, &conditional_value, &first_value, &second_value)
|
||||||
.map_err(|e| ExpressionError::cannot_enforce(format!("conditional select"), e, span))
|
.map_err(|e| ExpressionError::cannot_enforce("conditional select".to_string(), e, span))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,8 +70,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
Expression::Add(left, right, span) => {
|
Expression::Add(left, right, span) => {
|
||||||
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope,
|
||||||
function_scope.clone(),
|
function_scope,
|
||||||
expected_type,
|
expected_type,
|
||||||
*left,
|
*left,
|
||||||
*right,
|
*right,
|
||||||
@ -83,8 +83,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
Expression::Sub(left, right, span) => {
|
Expression::Sub(left, right, span) => {
|
||||||
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope,
|
||||||
function_scope.clone(),
|
function_scope,
|
||||||
expected_type,
|
expected_type,
|
||||||
*left,
|
*left,
|
||||||
*right,
|
*right,
|
||||||
@ -96,8 +96,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
Expression::Mul(left, right, span) => {
|
Expression::Mul(left, right, span) => {
|
||||||
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope,
|
||||||
function_scope.clone(),
|
function_scope,
|
||||||
expected_type,
|
expected_type,
|
||||||
*left,
|
*left,
|
||||||
*right,
|
*right,
|
||||||
@ -109,8 +109,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
Expression::Div(left, right, span) => {
|
Expression::Div(left, right, span) => {
|
||||||
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope,
|
||||||
function_scope.clone(),
|
function_scope,
|
||||||
expected_type,
|
expected_type,
|
||||||
*left,
|
*left,
|
||||||
*right,
|
*right,
|
||||||
@ -122,8 +122,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
Expression::Pow(left, right, span) => {
|
Expression::Pow(left, right, span) => {
|
||||||
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope,
|
||||||
function_scope.clone(),
|
function_scope,
|
||||||
expected_type,
|
expected_type,
|
||||||
*left,
|
*left,
|
||||||
*right,
|
*right,
|
||||||
@ -141,8 +141,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
Expression::Or(left, right, span) => {
|
Expression::Or(left, right, span) => {
|
||||||
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope,
|
||||||
function_scope.clone(),
|
function_scope,
|
||||||
expected_type,
|
expected_type,
|
||||||
*left,
|
*left,
|
||||||
*right,
|
*right,
|
||||||
@ -154,8 +154,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
Expression::And(left, right, span) => {
|
Expression::And(left, right, span) => {
|
||||||
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope,
|
||||||
function_scope.clone(),
|
function_scope,
|
||||||
expected_type,
|
expected_type,
|
||||||
*left,
|
*left,
|
||||||
*right,
|
*right,
|
||||||
@ -165,67 +165,32 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
Ok(enforce_and(cs, resolved_left, resolved_right, span)?)
|
Ok(enforce_and(cs, resolved_left, resolved_right, span)?)
|
||||||
}
|
}
|
||||||
Expression::Eq(left, right, span) => {
|
Expression::Eq(left, right, span) => {
|
||||||
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
let (resolved_left, resolved_right) =
|
||||||
cs,
|
self.enforce_binary_expression(cs, file_scope, function_scope, None, *left, *right, span.clone())?;
|
||||||
file_scope.clone(),
|
|
||||||
function_scope.clone(),
|
|
||||||
None,
|
|
||||||
*left,
|
|
||||||
*right,
|
|
||||||
span.clone(),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(evaluate_eq(cs, resolved_left, resolved_right, span)?)
|
Ok(evaluate_eq(cs, resolved_left, resolved_right, span)?)
|
||||||
}
|
}
|
||||||
Expression::Ge(left, right, span) => {
|
Expression::Ge(left, right, span) => {
|
||||||
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
let (resolved_left, resolved_right) =
|
||||||
cs,
|
self.enforce_binary_expression(cs, file_scope, function_scope, None, *left, *right, span.clone())?;
|
||||||
file_scope.clone(),
|
|
||||||
function_scope.clone(),
|
|
||||||
None,
|
|
||||||
*left,
|
|
||||||
*right,
|
|
||||||
span.clone(),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(evaluate_ge(cs, resolved_left, resolved_right, span)?)
|
Ok(evaluate_ge(cs, resolved_left, resolved_right, span)?)
|
||||||
}
|
}
|
||||||
Expression::Gt(left, right, span) => {
|
Expression::Gt(left, right, span) => {
|
||||||
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
let (resolved_left, resolved_right) =
|
||||||
cs,
|
self.enforce_binary_expression(cs, file_scope, function_scope, None, *left, *right, span.clone())?;
|
||||||
file_scope.clone(),
|
|
||||||
function_scope.clone(),
|
|
||||||
None,
|
|
||||||
*left,
|
|
||||||
*right,
|
|
||||||
span.clone(),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(evaluate_gt(cs, resolved_left, resolved_right, span)?)
|
Ok(evaluate_gt(cs, resolved_left, resolved_right, span)?)
|
||||||
}
|
}
|
||||||
Expression::Le(left, right, span) => {
|
Expression::Le(left, right, span) => {
|
||||||
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
let (resolved_left, resolved_right) =
|
||||||
cs,
|
self.enforce_binary_expression(cs, file_scope, function_scope, None, *left, *right, span.clone())?;
|
||||||
file_scope.clone(),
|
|
||||||
function_scope.clone(),
|
|
||||||
None,
|
|
||||||
*left,
|
|
||||||
*right,
|
|
||||||
span.clone(),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(evaluate_le(cs, resolved_left, resolved_right, span)?)
|
Ok(evaluate_le(cs, resolved_left, resolved_right, span)?)
|
||||||
}
|
}
|
||||||
Expression::Lt(left, right, span) => {
|
Expression::Lt(left, right, span) => {
|
||||||
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
let (resolved_left, resolved_right) =
|
||||||
cs,
|
self.enforce_binary_expression(cs, file_scope, function_scope, None, *left, *right, span.clone())?;
|
||||||
file_scope.clone(),
|
|
||||||
function_scope.clone(),
|
|
||||||
None,
|
|
||||||
*left,
|
|
||||||
*right,
|
|
||||||
span.clone(),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(evaluate_lt(cs, resolved_left, resolved_right, span)?)
|
Ok(evaluate_lt(cs, resolved_left, resolved_right, span)?)
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ use snarkos_models::{
|
|||||||
|
|
||||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||||
/// Call a default core circuit function with arguments
|
/// Call a default core circuit function with arguments
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn enforce_core_circuit_call_expression<CS: ConstraintSystem<F>>(
|
pub fn enforce_core_circuit_call_expression<CS: ConstraintSystem<F>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
cs: &mut CS,
|
cs: &mut CS,
|
||||||
@ -49,10 +50,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
let res = call_core_circuit(cs, core_circuit, argument_values, span.clone())?;
|
let res = call_core_circuit(cs, core_circuit, argument_values, span.clone())?;
|
||||||
|
|
||||||
// Convert the core function returns into constrained values
|
// Convert the core function returns into constrained values
|
||||||
let returns = res
|
let returns = res.into_iter().map(ConstrainedValue::from).collect::<Vec<_>>();
|
||||||
.into_iter()
|
|
||||||
.map(|value| ConstrainedValue::from(value))
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
let return_value = if returns.len() == 1 {
|
let return_value = if returns.len() == 1 {
|
||||||
// The function has a single return
|
// The function has a single return
|
||||||
@ -72,6 +70,6 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(return_value);
|
Ok(return_value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ use snarkos_models::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn enforce_function_call_expression<CS: ConstraintSystem<F>>(
|
pub fn enforce_function_call_expression<CS: ConstraintSystem<F>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
cs: &mut CS,
|
cs: &mut CS,
|
||||||
@ -35,7 +36,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
arguments: Vec<Expression>,
|
arguments: Vec<Expression>,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||||
let (declared_circuit_reference, function_value) = match *function.clone() {
|
let (declared_circuit_reference, function_value) = match *function {
|
||||||
Expression::CircuitMemberAccess(circuit_identifier, circuit_member, span) => {
|
Expression::CircuitMemberAccess(circuit_identifier, circuit_member, span) => {
|
||||||
// Call a circuit function that can mutate self.
|
// Call a circuit function that can mutate self.
|
||||||
|
|
||||||
@ -62,7 +63,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
let (outer_scope, function_call) = function_value.extract_function(file_scope.clone(), span.clone())?;
|
let (outer_scope, function_call) = function_value.extract_function(file_scope, span.clone())?;
|
||||||
|
|
||||||
let name_unique = format!(
|
let name_unique = format!(
|
||||||
"function call {} {}:{}",
|
"function call {} {}:{}",
|
||||||
|
@ -37,7 +37,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
unresolved_identifier: Identifier,
|
unresolved_identifier: Identifier,
|
||||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||||
// Evaluate the identifier name in the current function scope
|
// Evaluate the identifier name in the current function scope
|
||||||
let variable_name = new_scope(function_scope.clone(), unresolved_identifier.to_string());
|
let variable_name = new_scope(function_scope, unresolved_identifier.to_string());
|
||||||
let identifier_name = new_scope(file_scope, unresolved_identifier.to_string());
|
let identifier_name = new_scope(file_scope, unresolved_identifier.to_string());
|
||||||
|
|
||||||
let mut result_value = if let Some(value) = self.get(&variable_name) {
|
let mut result_value = if let Some(value) = self.get(&variable_name) {
|
||||||
@ -58,7 +58,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
return Err(ExpressionError::undefined_identifier(unresolved_identifier));
|
return Err(ExpressionError::undefined_identifier(unresolved_identifier));
|
||||||
};
|
};
|
||||||
|
|
||||||
result_value.resolve_type(expected_type, unresolved_identifier.span.clone())?;
|
result_value.resolve_type(expected_type, unresolved_identifier.span)?;
|
||||||
|
|
||||||
Ok(result_value)
|
Ok(result_value)
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ pub fn enforce_and<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<
|
|||||||
if let (ConstrainedValue::Boolean(left_bool), ConstrainedValue::Boolean(right_bool)) = (left, right) {
|
if let (ConstrainedValue::Boolean(left_bool), ConstrainedValue::Boolean(right_bool)) = (left, right) {
|
||||||
let name_unique = format!("{} {}:{}", name, span.line, span.start);
|
let name_unique = format!("{} {}:{}", name, span.line, span.start);
|
||||||
let result = Boolean::and(cs.ns(|| name_unique), &left_bool, &right_bool)
|
let result = Boolean::and(cs.ns(|| name_unique), &left_bool, &right_bool)
|
||||||
.map_err(|e| BooleanError::cannot_enforce(format!("&&"), e, span))?;
|
.map_err(|e| BooleanError::cannot_enforce("&&".to_string(), e, span))?;
|
||||||
|
|
||||||
return Ok(ConstrainedValue::Boolean(result));
|
return Ok(ConstrainedValue::Boolean(result));
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ pub fn enforce_or<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F
|
|||||||
if let (ConstrainedValue::Boolean(left_bool), ConstrainedValue::Boolean(right_bool)) = (left, right) {
|
if let (ConstrainedValue::Boolean(left_bool), ConstrainedValue::Boolean(right_bool)) = (left, right) {
|
||||||
let name_unique = format!("{} {}:{}", name, span.line, span.start);
|
let name_unique = format!("{} {}:{}", name, span.line, span.start);
|
||||||
let result = Boolean::or(cs.ns(|| name_unique), &left_bool, &right_bool)
|
let result = Boolean::or(cs.ns(|| name_unique), &left_bool, &right_bool)
|
||||||
.map_err(|e| BooleanError::cannot_enforce(format!("||"), e, span))?;
|
.map_err(|e| BooleanError::cannot_enforce("||".to_string(), e, span))?;
|
||||||
|
|
||||||
return Ok(ConstrainedValue::Boolean(result));
|
return Ok(ConstrainedValue::Boolean(result));
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,7 @@ pub fn evaluate_eq<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let boolean = constraint_result.map_err(|_| ExpressionError::cannot_evaluate(format!("=="), span))?;
|
let boolean = constraint_result.map_err(|_| ExpressionError::cannot_evaluate("==".to_string(), span))?;
|
||||||
|
|
||||||
Ok(ConstrainedValue::Boolean(boolean))
|
Ok(ConstrainedValue::Boolean(boolean))
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ pub fn evaluate_ge<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let boolean = constraint_result.map_err(|_| ExpressionError::cannot_evaluate(format!(">="), span))?;
|
let boolean = constraint_result.map_err(|_| ExpressionError::cannot_evaluate(">=".to_string(), span))?;
|
||||||
|
|
||||||
Ok(ConstrainedValue::Boolean(boolean))
|
Ok(ConstrainedValue::Boolean(boolean))
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ pub fn evaluate_gt<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let boolean = constraint_result.map_err(|_| ExpressionError::cannot_evaluate(format!(">"), span))?;
|
let boolean = constraint_result.map_err(|_| ExpressionError::cannot_evaluate(">".to_string(), span))?;
|
||||||
|
|
||||||
Ok(ConstrainedValue::Boolean(boolean))
|
Ok(ConstrainedValue::Boolean(boolean))
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ pub fn evaluate_le<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let boolean = constraint_result.map_err(|_| ExpressionError::cannot_evaluate(format!("<="), span))?;
|
let boolean = constraint_result.map_err(|_| ExpressionError::cannot_evaluate("<=".to_string(), span))?;
|
||||||
|
|
||||||
Ok(ConstrainedValue::Boolean(boolean))
|
Ok(ConstrainedValue::Boolean(boolean))
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ pub fn evaluate_lt<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let boolean = constraint_result.map_err(|_| ExpressionError::cannot_evaluate(format!("<"), span))?;
|
let boolean = constraint_result.map_err(|_| ExpressionError::cannot_evaluate("<".to_string(), span))?;
|
||||||
|
|
||||||
Ok(ConstrainedValue::Boolean(boolean))
|
Ok(ConstrainedValue::Boolean(boolean))
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ use snarkos_models::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn enforce_tuple_access<CS: ConstraintSystem<F>>(
|
pub fn enforce_tuple_access<CS: ConstraintSystem<F>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
cs: &mut CS,
|
cs: &mut CS,
|
||||||
@ -35,16 +36,9 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
index: usize,
|
index: usize,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||||
let tuple = match self.enforce_operand(
|
let tuple = match self.enforce_operand(cs, file_scope, function_scope, expected_type, *tuple, span.clone())? {
|
||||||
cs,
|
|
||||||
file_scope.clone(),
|
|
||||||
function_scope.clone(),
|
|
||||||
expected_type,
|
|
||||||
*tuple,
|
|
||||||
span.clone(),
|
|
||||||
)? {
|
|
||||||
ConstrainedValue::Tuple(tuple) => tuple,
|
ConstrainedValue::Tuple(tuple) => tuple,
|
||||||
value => return Err(ExpressionError::undefined_array(value.to_string(), span.clone())),
|
value => return Err(ExpressionError::undefined_array(value.to_string(), span)),
|
||||||
};
|
};
|
||||||
|
|
||||||
if index > tuple.len() - 1 {
|
if index > tuple.len() - 1 {
|
||||||
|
@ -38,19 +38,18 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
// Check explicit tuple type dimension if given
|
// Check explicit tuple type dimension if given
|
||||||
let mut expected_types = vec![];
|
let mut expected_types = vec![];
|
||||||
|
|
||||||
if expected_type.is_some() {
|
match expected_type {
|
||||||
match expected_type.unwrap() {
|
Some(Type::Tuple(ref types)) => {
|
||||||
Type::Tuple(ref types) => {
|
expected_types = types.clone();
|
||||||
expected_types = types.clone();
|
|
||||||
}
|
|
||||||
ref type_ => {
|
|
||||||
return Err(ExpressionError::unexpected_tuple(
|
|
||||||
type_.to_string(),
|
|
||||||
format!("{:?}", tuple),
|
|
||||||
span,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Some(ref type_) => {
|
||||||
|
return Err(ExpressionError::unexpected_tuple(
|
||||||
|
type_.to_string(),
|
||||||
|
format!("{:?}", tuple),
|
||||||
|
span,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut result = vec![];
|
let mut result = vec![];
|
||||||
|
@ -55,7 +55,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
check_arguments_length(function.input.len(), input.len(), function.span.clone())?;
|
check_arguments_length(function.input.len(), input.len(), function.span.clone())?;
|
||||||
|
|
||||||
// Store input values as new variables in resolved program
|
// Store input values as new variables in resolved program
|
||||||
for (input_model, input_expression) in function.input.clone().iter().zip(input.into_iter()) {
|
for (input_model, input_expression) in function.input.iter().zip(input.into_iter()) {
|
||||||
let (name, value) = match input_model {
|
let (name, value) = match input_model {
|
||||||
InputVariable::InputKeyword(identifier) => {
|
InputVariable::InputKeyword(identifier) => {
|
||||||
let input_value = self.enforce_function_input(
|
let input_value = self.enforce_function_input(
|
||||||
|
@ -54,7 +54,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
let name = input_model.identifier.name.clone();
|
let name = input_model.identifier.name.clone();
|
||||||
let input_option = input
|
let input_option = input
|
||||||
.get(&name)
|
.get(&name)
|
||||||
.ok_or(FunctionError::input_not_found(name.clone(), function.span.clone()))?;
|
.ok_or_else(|| FunctionError::input_not_found(name.clone(), function.span.clone()))?;
|
||||||
let input_value = self.allocate_main_function_input(
|
let input_value = self.allocate_main_function_input(
|
||||||
cs,
|
cs,
|
||||||
input_model.type_,
|
input_model.type_,
|
||||||
|
@ -37,14 +37,14 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
span: Span,
|
span: Span,
|
||||||
) -> Result<(), StatementError> {
|
) -> Result<(), StatementError> {
|
||||||
// if there are no results, continue
|
// if there are no results, continue
|
||||||
if results.len() == 0 {
|
if results.is_empty() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
// If all indicators are none, then there are no branch conditions in the function.
|
// If all indicators are none, then there are no branch conditions in the function.
|
||||||
// We simply return the last result.
|
// We simply return the last result.
|
||||||
|
|
||||||
if let None = results.iter().find(|(indicator, _res)| indicator.is_some()) {
|
if results.iter().all(|(indicator, _res)| indicator.is_none()) {
|
||||||
let result = &results[results.len() - 1].1;
|
let result = &results[results.len() - 1].1;
|
||||||
|
|
||||||
*return_value = result.clone();
|
*return_value = result.clone();
|
||||||
|
@ -21,7 +21,7 @@ use std::{collections::HashMap, env::current_dir};
|
|||||||
|
|
||||||
/// Parses all relevant import files for a program.
|
/// Parses all relevant import files for a program.
|
||||||
/// Stores compiled program structs.
|
/// Stores compiled program structs.
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Default)]
|
||||||
pub struct ImportParser {
|
pub struct ImportParser {
|
||||||
imports: HashMap<String, Program>,
|
imports: HashMap<String, Program>,
|
||||||
core_packages: Vec<Package>,
|
core_packages: Vec<Package>,
|
||||||
@ -29,10 +29,7 @@ pub struct ImportParser {
|
|||||||
|
|
||||||
impl ImportParser {
|
impl ImportParser {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self::default()
|
||||||
imports: HashMap::new(),
|
|
||||||
core_packages: vec![],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn insert_import(&mut self, file_name: String, program: Program) {
|
pub(crate) fn insert_import(&mut self, file_name: String, program: Program) {
|
||||||
@ -44,7 +41,7 @@ impl ImportParser {
|
|||||||
let _res = self.core_packages.push(package.clone());
|
let _res = self.core_packages.push(package.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_import(&self, file_name: &String) -> Option<&Program> {
|
pub fn get_import(&self, file_name: &str) -> Option<&Program> {
|
||||||
self.imports.get(file_name)
|
self.imports.get(file_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +53,7 @@ impl ImportParser {
|
|||||||
let mut imports = Self::new();
|
let mut imports = Self::new();
|
||||||
|
|
||||||
// Find all imports relative to current directory
|
// Find all imports relative to current directory
|
||||||
let path = current_dir().map_err(|error| ImportError::current_directory_error(error))?;
|
let path = current_dir().map_err(ImportError::current_directory_error)?;
|
||||||
|
|
||||||
// Parse each imported file
|
// Parse each imported file
|
||||||
program
|
program
|
||||||
|
@ -70,14 +70,12 @@ impl ImportParser {
|
|||||||
|
|
||||||
let entries = fs::read_dir(path)
|
let entries = fs::read_dir(path)
|
||||||
.map_err(|error| ImportError::directory_error(error, package_name.span.clone(), error_path.clone()))?
|
.map_err(|error| ImportError::directory_error(error, package_name.span.clone(), error_path.clone()))?
|
||||||
.into_iter()
|
|
||||||
.collect::<Result<Vec<_>, std::io::Error>>()
|
.collect::<Result<Vec<_>, std::io::Error>>()
|
||||||
.map_err(|error| ImportError::directory_error(error, package_name.span.clone(), error_path.clone()))?;
|
.map_err(|error| ImportError::directory_error(error, package_name.span.clone(), error_path.clone()))?;
|
||||||
|
|
||||||
let matched_source_entry = entries.into_iter().find(|entry| {
|
let matched_source_entry = entries.into_iter().find(|entry| {
|
||||||
entry
|
entry
|
||||||
.file_name()
|
.file_name()
|
||||||
.to_os_string()
|
|
||||||
.into_string()
|
.into_string()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.trim_end_matches(SOURCE_FILE_EXTENSION)
|
.trim_end_matches(SOURCE_FILE_EXTENSION)
|
||||||
@ -90,7 +88,6 @@ impl ImportParser {
|
|||||||
} else if imports_directory.exists() {
|
} else if imports_directory.exists() {
|
||||||
let entries = fs::read_dir(imports_directory)
|
let entries = fs::read_dir(imports_directory)
|
||||||
.map_err(|error| ImportError::directory_error(error, package_name.span.clone(), error_path.clone()))?
|
.map_err(|error| ImportError::directory_error(error, package_name.span.clone(), error_path.clone()))?
|
||||||
.into_iter()
|
|
||||||
.collect::<Result<Vec<_>, std::io::Error>>()
|
.collect::<Result<Vec<_>, std::io::Error>>()
|
||||||
.map_err(|error| ImportError::directory_error(error, package_name.span.clone(), error_path.clone()))?;
|
.map_err(|error| ImportError::directory_error(error, package_name.span.clone(), error_path.clone()))?;
|
||||||
|
|
||||||
|
@ -30,11 +30,10 @@ fn parse_import_file(entry: &DirEntry, span: &Span) -> Result<Program, ImportErr
|
|||||||
.map_err(|error| ImportError::directory_error(error, span.clone(), entry.path()))?;
|
.map_err(|error| ImportError::directory_error(error, span.clone(), entry.path()))?;
|
||||||
let file_name = entry
|
let file_name = entry
|
||||||
.file_name()
|
.file_name()
|
||||||
.to_os_string()
|
|
||||||
.into_string()
|
.into_string()
|
||||||
.map_err(|_| ImportError::convert_os_string(span.clone()))?;
|
.map_err(|_| ImportError::convert_os_string(span.clone()))?;
|
||||||
|
|
||||||
let mut file_path = entry.path().to_path_buf();
|
let mut file_path = entry.path();
|
||||||
if file_type.is_dir() {
|
if file_type.is_dir() {
|
||||||
file_path.push(LIBRARY_FILE);
|
file_path.push(LIBRARY_FILE);
|
||||||
|
|
||||||
@ -62,7 +61,7 @@ impl ImportParser {
|
|||||||
.extension()
|
.extension()
|
||||||
.map_or(false, |ext| ext.eq(&OsString::from(FILE_EXTENSION)));
|
.map_or(false, |ext| ext.eq(&OsString::from(FILE_EXTENSION)));
|
||||||
|
|
||||||
let mut package_path = path.to_path_buf();
|
let mut package_path = path;
|
||||||
package_path.push(LIBRARY_FILE);
|
package_path.push(LIBRARY_FILE);
|
||||||
|
|
||||||
let is_package = is_dir && package_path.exists();
|
let is_package = is_dir && package_path.exists();
|
||||||
@ -93,7 +92,7 @@ impl ImportParser {
|
|||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
// importing * from a directory or non-leo file in `package/src/` is illegal
|
// importing * from a directory or non-leo file in `package/src/` is illegal
|
||||||
Err(ImportError::star(entry.path().to_path_buf(), span.clone()))
|
Err(ImportError::star(entry.path(), span.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
.find(|package| import.package.eq(package));
|
.find(|package| import.package.eq(package));
|
||||||
|
|
||||||
if let Some(package) = core_dependency {
|
if let Some(package) = core_dependency {
|
||||||
self.store_core_package(scope.clone(), package.clone())?;
|
self.store_core_package(scope, package.clone())?;
|
||||||
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@ -45,7 +45,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
// Find imported program
|
// Find imported program
|
||||||
let program = imported_programs
|
let program = imported_programs
|
||||||
.get_import(&package)
|
.get_import(&package)
|
||||||
.ok_or(ImportError::unknown_package(import.package.name.clone()))?;
|
.ok_or_else(|| ImportError::unknown_package(import.package.name.clone()))?;
|
||||||
|
|
||||||
// Parse imported program
|
// Parse imported program
|
||||||
self.store_definitions(program.clone(), imported_programs)?;
|
self.store_definitions(program.clone(), imported_programs)?;
|
||||||
|
@ -59,7 +59,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
|
|
||||||
let value = match matched_circuit {
|
let value = match matched_circuit {
|
||||||
Some((_circuit_name, circuit)) => ConstrainedValue::Import(
|
Some((_circuit_name, circuit)) => ConstrainedValue::Import(
|
||||||
program_name.clone(),
|
program_name,
|
||||||
Box::new(ConstrainedValue::CircuitDefinition(circuit.clone())),
|
Box::new(ConstrainedValue::CircuitDefinition(circuit.clone())),
|
||||||
),
|
),
|
||||||
None => {
|
None => {
|
||||||
@ -71,7 +71,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
|
|
||||||
match matched_function {
|
match matched_function {
|
||||||
Some((_function_name, function)) => ConstrainedValue::Import(
|
Some((_function_name, function)) => ConstrainedValue::Import(
|
||||||
program_name.clone(),
|
program_name,
|
||||||
Box::new(ConstrainedValue::Function(None, function.clone())),
|
Box::new(ConstrainedValue::Function(None, function.clone())),
|
||||||
),
|
),
|
||||||
None => return Err(ImportError::unknown_symbol(symbol.to_owned(), program_name)),
|
None => return Err(ImportError::unknown_symbol(symbol.to_owned(), program_name)),
|
||||||
@ -80,7 +80,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// take the alias if it is present
|
// take the alias if it is present
|
||||||
let id = symbol.alias.clone().unwrap_or(symbol.symbol.clone());
|
let id = symbol.alias.clone().unwrap_or_else(|| symbol.symbol.clone());
|
||||||
let name = new_scope(scope, id.to_string());
|
let name = new_scope(scope, id.to_string());
|
||||||
|
|
||||||
// store imported circuit under imported name
|
// store imported circuit under imported name
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
//! Module containing structs and types that make up a Leo program.
|
//! Module containing structs and types that make up a Leo program.
|
||||||
|
|
||||||
|
#![allow(clippy::module_inception)]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate thiserror;
|
extern crate thiserror;
|
||||||
|
|
||||||
|
@ -27,30 +27,36 @@ pub struct ConstrainedProgram<F: Field + PrimeField, G: GroupType<F>> {
|
|||||||
pub identifiers: HashMap<String, ConstrainedValue<F, G>>,
|
pub identifiers: HashMap<String, ConstrainedValue<F, G>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<F: Field + PrimeField, G: GroupType<F>> Default for ConstrainedProgram<F, G> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
identifiers: HashMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn new_scope(outer: String, inner: String) -> String {
|
pub fn new_scope(outer: String, inner: String) -> String {
|
||||||
format!("{}_{}", outer, inner)
|
format!("{}_{}", outer, inner)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_in_scope(current_scope: &String, desired_scope: &String) -> bool {
|
pub fn is_in_scope(current_scope: &str, desired_scope: &str) -> bool {
|
||||||
current_scope.ends_with(desired_scope)
|
current_scope.ends_with(desired_scope)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self::default()
|
||||||
identifiers: HashMap::new(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn store(&mut self, name: String, value: ConstrainedValue<F, G>) {
|
pub(crate) fn store(&mut self, name: String, value: ConstrainedValue<F, G>) {
|
||||||
self.identifiers.insert(name, value);
|
self.identifiers.insert(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get(&self, name: &String) -> Option<&ConstrainedValue<F, G>> {
|
pub(crate) fn get(&self, name: &str) -> Option<&ConstrainedValue<F, G>> {
|
||||||
self.identifiers.get(name)
|
self.identifiers.get(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_mut(&mut self, name: &String) -> Option<&mut ConstrainedValue<F, G>> {
|
pub(crate) fn get_mut(&mut self, name: &str) -> Option<&mut ConstrainedValue<F, G>> {
|
||||||
self.identifiers.get_mut(name)
|
self.identifiers.get_mut(name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ use snarkos_models::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn assign_array<CS: ConstraintSystem<F>>(
|
pub fn assign_array<CS: ConstraintSystem<F>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
cs: &mut CS,
|
cs: &mut CS,
|
||||||
@ -44,7 +45,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
// Resolve index so we know if we are assigning to a single value or a range of values
|
// Resolve index so we know if we are assigning to a single value or a range of values
|
||||||
match range_or_expression {
|
match range_or_expression {
|
||||||
RangeOrExpression::Expression(index) => {
|
RangeOrExpression::Expression(index) => {
|
||||||
let index = self.enforce_index(cs, file_scope.clone(), function_scope.clone(), index, span.clone())?;
|
let index = self.enforce_index(cs, file_scope, function_scope, index, span.clone())?;
|
||||||
|
|
||||||
// Modify the single value of the array in place
|
// Modify the single value of the array in place
|
||||||
match self.get_mutable_assignee(name, span.clone())? {
|
match self.get_mutable_assignee(name, span.clone())? {
|
||||||
@ -75,13 +76,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
None => 0usize,
|
None => 0usize,
|
||||||
};
|
};
|
||||||
let to_index_option = match to {
|
let to_index_option = match to {
|
||||||
Some(integer) => Some(self.enforce_index(
|
Some(integer) => Some(self.enforce_index(cs, file_scope, function_scope, integer, span.clone())?),
|
||||||
cs,
|
|
||||||
file_scope.clone(),
|
|
||||||
function_scope.clone(),
|
|
||||||
integer,
|
|
||||||
span.clone(),
|
|
||||||
)?),
|
|
||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ use snarkos_models::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn enforce_assign_statement<CS: ConstraintSystem<F>>(
|
pub fn enforce_assign_statement<CS: ConstraintSystem<F>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
cs: &mut CS,
|
cs: &mut CS,
|
||||||
@ -57,7 +58,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
match assignee {
|
match assignee {
|
||||||
Assignee::Identifier(_identifier) => {
|
Assignee::Identifier(_identifier) => {
|
||||||
let condition = indicator.unwrap_or(Boolean::Constant(true));
|
let condition = indicator.unwrap_or(Boolean::Constant(true));
|
||||||
let old_value = self.get_mutable_assignee(variable_name.clone(), span.clone())?;
|
let old_value = self.get_mutable_assignee(variable_name, span.clone())?;
|
||||||
|
|
||||||
new_value.resolve_type(Some(old_value.to_type(span.clone())?), span.clone())?;
|
new_value.resolve_type(Some(old_value.to_type(span.clone())?), span.clone())?;
|
||||||
|
|
||||||
@ -76,7 +77,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
function_scope,
|
function_scope,
|
||||||
indicator,
|
indicator,
|
||||||
variable_name,
|
variable_name,
|
||||||
range_or_expression,
|
*range_or_expression,
|
||||||
new_value,
|
new_value,
|
||||||
span,
|
span,
|
||||||
),
|
),
|
||||||
|
@ -43,7 +43,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
match self.get_mutable_assignee(circuit_name, span.clone())? {
|
match self.get_mutable_assignee(circuit_name, span.clone())? {
|
||||||
ConstrainedValue::CircuitExpression(_variable, members) => {
|
ConstrainedValue::CircuitExpression(_variable, members) => {
|
||||||
// Modify the circuit variable in place
|
// Modify the circuit variable in place
|
||||||
let matched_variable = members.into_iter().find(|member| member.0 == variable_name);
|
let matched_variable = members.iter_mut().find(|member| member.0 == variable_name);
|
||||||
|
|
||||||
match matched_variable {
|
match matched_variable {
|
||||||
Some(member) => match &member.1 {
|
Some(member) => match &member.1 {
|
||||||
@ -81,7 +81,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
|
|
||||||
member.1 = selected_value.to_owned();
|
member.1 = selected_value.to_owned();
|
||||||
|
|
||||||
Ok(selected_value.to_owned())
|
Ok(selected_value)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// Throw an error if we try to mutate an immutable circuit variable
|
// Throw an error if we try to mutate an immutable circuit variable
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
//! Enforces a branch of a conditional or iteration statement in a compiled Leo program.
|
//! Enforces a branch of a conditional or iteration statement in a compiled Leo program.
|
||||||
|
|
||||||
use crate::{errors::StatementError, program::ConstrainedProgram, value::ConstrainedValue, GroupType};
|
use crate::{program::ConstrainedProgram, GroupType, IndicatorAndConstrainedValue, StatementResult};
|
||||||
use leo_typed::{Statement, Type};
|
use leo_typed::{Statement, Type};
|
||||||
|
|
||||||
use snarkos_models::{
|
use snarkos_models::{
|
||||||
@ -33,7 +33,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
indicator: Option<Boolean>,
|
indicator: Option<Boolean>,
|
||||||
statements: Vec<Statement>,
|
statements: Vec<Statement>,
|
||||||
return_type: Option<Type>,
|
return_type: Option<Type>,
|
||||||
) -> Result<Vec<(Option<Boolean>, ConstrainedValue<F, G>)>, StatementError> {
|
) -> StatementResult<Vec<IndicatorAndConstrainedValue<F, G>>> {
|
||||||
let mut results = vec![];
|
let mut results = vec![];
|
||||||
// Evaluate statements. Only allow a single return argument to be returned.
|
// Evaluate statements. Only allow a single return argument to be returned.
|
||||||
for statement in statements.iter() {
|
for statement in statements.iter() {
|
||||||
@ -41,7 +41,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope.clone(),
|
||||||
function_scope.clone(),
|
function_scope.clone(),
|
||||||
indicator.clone(),
|
indicator,
|
||||||
statement.clone(),
|
statement.clone(),
|
||||||
return_type.clone(),
|
return_type.clone(),
|
||||||
"".to_owned(),
|
"".to_owned(),
|
||||||
|
@ -16,7 +16,14 @@
|
|||||||
|
|
||||||
//! Methods to enforce constraints on statements in a compiled Leo program.
|
//! Methods to enforce constraints on statements in a compiled Leo program.
|
||||||
|
|
||||||
use crate::{errors::StatementError, program::ConstrainedProgram, value::ConstrainedValue, GroupType};
|
use crate::{
|
||||||
|
errors::StatementError,
|
||||||
|
program::ConstrainedProgram,
|
||||||
|
value::ConstrainedValue,
|
||||||
|
GroupType,
|
||||||
|
IndicatorAndConstrainedValue,
|
||||||
|
StatementResult,
|
||||||
|
};
|
||||||
use leo_typed::{ConditionalNestedOrEndStatement, ConditionalStatement, Span, Type};
|
use leo_typed::{ConditionalNestedOrEndStatement, ConditionalStatement, Span, Type};
|
||||||
|
|
||||||
use snarkos_models::{
|
use snarkos_models::{
|
||||||
@ -28,7 +35,7 @@ fn indicator_to_string(indicator: &Boolean) -> String {
|
|||||||
indicator
|
indicator
|
||||||
.get_value()
|
.get_value()
|
||||||
.map(|b| b.to_string())
|
.map(|b| b.to_string())
|
||||||
.unwrap_or(format!("[input]"))
|
.unwrap_or_else(|| "[input]".to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||||
@ -36,6 +43,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
/// Due to R1CS constraints, we must evaluate every branch to properly construct the circuit.
|
/// Due to R1CS constraints, we must evaluate every branch to properly construct the circuit.
|
||||||
/// At program execution, we will pass an `indicator` bit down to all child statements within each branch.
|
/// At program execution, we will pass an `indicator` bit down to all child statements within each branch.
|
||||||
/// The `indicator` bit will select that branch while keeping the constraint system satisfied.
|
/// The `indicator` bit will select that branch while keeping the constraint system satisfied.
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn enforce_conditional_statement<CS: ConstraintSystem<F>>(
|
pub fn enforce_conditional_statement<CS: ConstraintSystem<F>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
cs: &mut CS,
|
cs: &mut CS,
|
||||||
@ -45,7 +53,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
statement: ConditionalStatement,
|
statement: ConditionalStatement,
|
||||||
return_type: Option<Type>,
|
return_type: Option<Type>,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> Result<Vec<(Option<Boolean>, ConstrainedValue<F, G>)>, StatementError> {
|
) -> StatementResult<Vec<IndicatorAndConstrainedValue<F, G>>> {
|
||||||
let statement_string = statement.to_string();
|
let statement_string = statement.to_string();
|
||||||
|
|
||||||
// Inherit the indicator from a previous conditional statement or assume that we are the outer parent
|
// Inherit the indicator from a previous conditional statement or assume that we are the outer parent
|
||||||
|
@ -56,15 +56,15 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
) -> Result<Vec<ConstrainedValue<F, G>>, StatementError> {
|
) -> Result<Vec<ConstrainedValue<F, G>>, StatementError> {
|
||||||
let types = match type_ {
|
let types = match type_ {
|
||||||
Some(Type::Tuple(types)) => types,
|
Some(Type::Tuple(types)) => types,
|
||||||
Some(type_) => return Err(StatementError::tuple_type(type_.to_string(), span.clone())),
|
Some(type_) => return Err(StatementError::tuple_type(type_.to_string(), span)),
|
||||||
None => vec![],
|
None => vec![],
|
||||||
};
|
};
|
||||||
|
|
||||||
let implicit_types = types.is_empty();
|
let implicit_types = types.is_empty();
|
||||||
let mut expected_types = vec![];
|
let mut expected_types = vec![];
|
||||||
|
|
||||||
for i in 0..expressions.len() {
|
for ty in types.iter().take(expressions.len()) {
|
||||||
let expected_type = if implicit_types { None } else { Some(types[i].clone()) };
|
let expected_type = if implicit_types { None } else { Some(ty.clone()) };
|
||||||
|
|
||||||
expected_types.push(expected_type);
|
expected_types.push(expected_type);
|
||||||
}
|
}
|
||||||
@ -86,6 +86,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
Ok(values)
|
Ok(values)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn enforce_tuple_definition<CS: ConstraintSystem<F>>(
|
fn enforce_tuple_definition<CS: ConstraintSystem<F>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
cs: &mut CS,
|
cs: &mut CS,
|
||||||
@ -135,6 +136,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn enforce_definition_statement<CS: ConstraintSystem<F>>(
|
pub fn enforce_definition_statement<CS: ConstraintSystem<F>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
cs: &mut CS,
|
cs: &mut CS,
|
||||||
@ -157,7 +159,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
let variable = variables.names[0].clone();
|
let variable = variables.names[0].clone();
|
||||||
let expression = self.enforce_expression(
|
let expression = self.enforce_expression(
|
||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope,
|
||||||
function_scope.clone(),
|
function_scope.clone(),
|
||||||
variables.type_,
|
variables.type_,
|
||||||
expressions[0].clone(),
|
expressions[0].clone(),
|
||||||
@ -181,14 +183,14 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
|
|
||||||
let values = match self.enforce_expression(
|
let values = match self.enforce_expression(
|
||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope,
|
||||||
function_scope.clone(),
|
function_scope.clone(),
|
||||||
variables.type_.clone(),
|
variables.type_.clone(),
|
||||||
expressions[0].clone(),
|
expressions[0].clone(),
|
||||||
)? {
|
)? {
|
||||||
// ConstrainedValue::Return(values) => values,
|
// ConstrainedValue::Return(values) => values,
|
||||||
ConstrainedValue::Tuple(values) => values,
|
ConstrainedValue::Tuple(values) => values,
|
||||||
value => return Err(StatementError::multiple_definition(value.to_string(), span.clone())),
|
value => return Err(StatementError::multiple_definition(value.to_string(), span)),
|
||||||
};
|
};
|
||||||
|
|
||||||
self.enforce_multiple_definition(cs, function_scope, is_constant, variables, values, span)
|
self.enforce_multiple_definition(cs, function_scope, is_constant, variables, values, span)
|
||||||
|
@ -17,12 +17,13 @@
|
|||||||
//! Enforces an iteration statement in a compiled Leo program.
|
//! Enforces an iteration statement in a compiled Leo program.
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
errors::StatementError,
|
|
||||||
new_scope,
|
new_scope,
|
||||||
program::ConstrainedProgram,
|
program::ConstrainedProgram,
|
||||||
value::ConstrainedValue,
|
value::ConstrainedValue,
|
||||||
GroupType,
|
GroupType,
|
||||||
|
IndicatorAndConstrainedValue,
|
||||||
Integer,
|
Integer,
|
||||||
|
StatementResult,
|
||||||
};
|
};
|
||||||
use leo_typed::{Expression, Identifier, Span, Statement, Type};
|
use leo_typed::{Expression, Identifier, Span, Statement, Type};
|
||||||
|
|
||||||
@ -35,6 +36,7 @@ use snarkos_models::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn enforce_iteration_statement<CS: ConstraintSystem<F>>(
|
pub fn enforce_iteration_statement<CS: ConstraintSystem<F>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
cs: &mut CS,
|
cs: &mut CS,
|
||||||
@ -47,7 +49,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
statements: Vec<Statement>,
|
statements: Vec<Statement>,
|
||||||
return_type: Option<Type>,
|
return_type: Option<Type>,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> Result<Vec<(Option<Boolean>, ConstrainedValue<F, G>)>, StatementError> {
|
) -> StatementResult<Vec<IndicatorAndConstrainedValue<F, G>>> {
|
||||||
let mut results = vec![];
|
let mut results = vec![];
|
||||||
|
|
||||||
let from = self.enforce_index(cs, file_scope.clone(), function_scope.clone(), start, span.clone())?;
|
let from = self.enforce_index(cs, file_scope.clone(), function_scope.clone(), start, span.clone())?;
|
||||||
|
@ -28,9 +28,7 @@ fn check_return_type(expected: Option<Type>, actual: Type, span: Span) -> Result
|
|||||||
match expected {
|
match expected {
|
||||||
Some(expected) => {
|
Some(expected) => {
|
||||||
if expected.ne(&actual) {
|
if expected.ne(&actual) {
|
||||||
if expected.is_self() && actual.is_circuit() {
|
if (expected.is_self() && actual.is_circuit()) || expected.match_array_types(&actual) {
|
||||||
return Ok(());
|
|
||||||
} else if expected.match_array_types(&actual) {
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
} else {
|
} else {
|
||||||
return Err(StatementError::arguments_type(&expected, &actual, span));
|
return Err(StatementError::arguments_type(&expected, &actual, span));
|
||||||
@ -56,8 +54,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
|
|
||||||
let result = self.enforce_operand(
|
let result = self.enforce_operand(
|
||||||
cs,
|
cs,
|
||||||
file_scope.clone(),
|
file_scope,
|
||||||
function_scope.clone(),
|
function_scope,
|
||||||
return_type.clone(),
|
return_type.clone(),
|
||||||
expression,
|
expression,
|
||||||
span.clone(),
|
span.clone(),
|
||||||
|
@ -24,12 +24,16 @@ use snarkos_models::{
|
|||||||
gadgets::{r1cs::ConstraintSystem, utilities::boolean::Boolean},
|
gadgets::{r1cs::ConstraintSystem, utilities::boolean::Boolean},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub type StatementResult<T> = Result<T, StatementError>;
|
||||||
|
pub type IndicatorAndConstrainedValue<T, U> = (Option<Boolean>, ConstrainedValue<T, U>);
|
||||||
|
|
||||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||||
/// Enforce a program statement.
|
/// Enforce a program statement.
|
||||||
/// Returns a Vector of (indicator, value) tuples.
|
/// Returns a Vector of (indicator, value) tuples.
|
||||||
/// Each evaluated statement may execute of one or more statements that may return early.
|
/// Each evaluated statement may execute of one or more statements that may return early.
|
||||||
/// To indicate which of these return values to take we conditionally select the value according
|
/// To indicate which of these return values to take we conditionally select the value according
|
||||||
/// to the `indicator` bit that evaluates to true.
|
/// to the `indicator` bit that evaluates to true.
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn enforce_statement<CS: ConstraintSystem<F>>(
|
pub fn enforce_statement<CS: ConstraintSystem<F>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
cs: &mut CS,
|
cs: &mut CS,
|
||||||
@ -39,7 +43,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
statement: Statement,
|
statement: Statement,
|
||||||
return_type: Option<Type>,
|
return_type: Option<Type>,
|
||||||
declared_circuit_reference: String,
|
declared_circuit_reference: String,
|
||||||
) -> Result<Vec<(Option<Boolean>, ConstrainedValue<F, G>)>, StatementError> {
|
) -> StatementResult<Vec<IndicatorAndConstrainedValue<F, G>>> {
|
||||||
let mut results = vec![];
|
let mut results = vec![];
|
||||||
|
|
||||||
match statement {
|
match statement {
|
||||||
@ -70,7 +74,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
declared_circuit_reference,
|
declared_circuit_reference,
|
||||||
indicator,
|
indicator,
|
||||||
variable,
|
variable,
|
||||||
expression,
|
*expression,
|
||||||
span,
|
span,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
@ -94,8 +98,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
function_scope,
|
function_scope,
|
||||||
indicator,
|
indicator,
|
||||||
index,
|
index,
|
||||||
start,
|
*start,
|
||||||
stop,
|
*stop,
|
||||||
statements,
|
statements,
|
||||||
return_type,
|
return_type,
|
||||||
span,
|
span,
|
||||||
|
@ -153,7 +153,7 @@ impl<F: Field + PrimeField> AllocGadget<String, F> for Address {
|
|||||||
impl<F: Field + PrimeField> EvaluateEqGadget<F> for Address {
|
impl<F: Field + PrimeField> EvaluateEqGadget<F> for Address {
|
||||||
fn evaluate_equal<CS: ConstraintSystem<F>>(&self, mut cs: CS, other: &Self) -> Result<Boolean, SynthesisError> {
|
fn evaluate_equal<CS: ConstraintSystem<F>>(&self, mut cs: CS, other: &Self) -> Result<Boolean, SynthesisError> {
|
||||||
if self.is_constant() && other.is_constant() {
|
if self.is_constant() && other.is_constant() {
|
||||||
return Ok(Boolean::Constant(self.eq(other)));
|
Ok(Boolean::Constant(self.eq(other)))
|
||||||
} else {
|
} else {
|
||||||
let mut result = Boolean::constant(true);
|
let mut result = Boolean::constant(true);
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ impl<F: Field + PrimeField> FieldType<F> {
|
|||||||
(FieldType::Allocated(self_value), FieldType::Allocated(other_value)) => {
|
(FieldType::Allocated(self_value), FieldType::Allocated(other_value)) => {
|
||||||
let result = self_value
|
let result = self_value
|
||||||
.add(cs, other_value)
|
.add(cs, other_value)
|
||||||
.map_err(|e| FieldError::binary_operation(format!("+"), e, span))?;
|
.map_err(|e| FieldError::binary_operation("+".to_string(), e, span))?;
|
||||||
|
|
||||||
Ok(FieldType::Allocated(result))
|
Ok(FieldType::Allocated(result))
|
||||||
}
|
}
|
||||||
@ -88,7 +88,7 @@ impl<F: Field + PrimeField> FieldType<F> {
|
|||||||
| (FieldType::Allocated(allocated_value), FieldType::Constant(constant_value)) => Ok(FieldType::Allocated(
|
| (FieldType::Allocated(allocated_value), FieldType::Constant(constant_value)) => Ok(FieldType::Allocated(
|
||||||
allocated_value
|
allocated_value
|
||||||
.add_constant(cs, constant_value)
|
.add_constant(cs, constant_value)
|
||||||
.map_err(|e| FieldError::binary_operation(format!("+"), e, span))?,
|
.map_err(|e| FieldError::binary_operation("+".to_string(), e, span))?,
|
||||||
)),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -102,7 +102,7 @@ impl<F: Field + PrimeField> FieldType<F> {
|
|||||||
(FieldType::Allocated(self_value), FieldType::Allocated(other_value)) => {
|
(FieldType::Allocated(self_value), FieldType::Allocated(other_value)) => {
|
||||||
let result = self_value
|
let result = self_value
|
||||||
.sub(cs, other_value)
|
.sub(cs, other_value)
|
||||||
.map_err(|e| FieldError::binary_operation(format!("-"), e, span))?;
|
.map_err(|e| FieldError::binary_operation("-".to_string(), e, span))?;
|
||||||
|
|
||||||
Ok(FieldType::Allocated(result))
|
Ok(FieldType::Allocated(result))
|
||||||
}
|
}
|
||||||
@ -111,7 +111,7 @@ impl<F: Field + PrimeField> FieldType<F> {
|
|||||||
| (FieldType::Allocated(allocated_value), FieldType::Constant(constant_value)) => Ok(FieldType::Allocated(
|
| (FieldType::Allocated(allocated_value), FieldType::Constant(constant_value)) => Ok(FieldType::Allocated(
|
||||||
allocated_value
|
allocated_value
|
||||||
.sub_constant(cs, constant_value)
|
.sub_constant(cs, constant_value)
|
||||||
.map_err(|e| FieldError::binary_operation(format!("+"), e, span))?,
|
.map_err(|e| FieldError::binary_operation("+".to_string(), e, span))?,
|
||||||
)),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -125,7 +125,7 @@ impl<F: Field + PrimeField> FieldType<F> {
|
|||||||
(FieldType::Allocated(self_value), FieldType::Allocated(other_value)) => {
|
(FieldType::Allocated(self_value), FieldType::Allocated(other_value)) => {
|
||||||
let result = self_value
|
let result = self_value
|
||||||
.mul(cs, other_value)
|
.mul(cs, other_value)
|
||||||
.map_err(|e| FieldError::binary_operation(format!("*"), e, span))?;
|
.map_err(|e| FieldError::binary_operation("*".to_string(), e, span))?;
|
||||||
|
|
||||||
Ok(FieldType::Allocated(result))
|
Ok(FieldType::Allocated(result))
|
||||||
}
|
}
|
||||||
@ -134,7 +134,7 @@ impl<F: Field + PrimeField> FieldType<F> {
|
|||||||
| (FieldType::Allocated(allocated_value), FieldType::Constant(constant_value)) => Ok(FieldType::Allocated(
|
| (FieldType::Allocated(allocated_value), FieldType::Constant(constant_value)) => Ok(FieldType::Allocated(
|
||||||
allocated_value
|
allocated_value
|
||||||
.mul_by_constant(cs, constant_value)
|
.mul_by_constant(cs, constant_value)
|
||||||
.map_err(|e| FieldError::binary_operation(format!("*"), e, span))?,
|
.map_err(|e| FieldError::binary_operation("*".to_string(), e, span))?,
|
||||||
)),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -144,14 +144,14 @@ impl<F: Field + PrimeField> FieldType<F> {
|
|||||||
FieldType::Constant(constant) => {
|
FieldType::Constant(constant) => {
|
||||||
let constant_inverse = constant
|
let constant_inverse = constant
|
||||||
.inverse()
|
.inverse()
|
||||||
.ok_or(FieldError::no_inverse(constant.to_string(), span.clone()))?;
|
.ok_or_else(|| FieldError::no_inverse(constant.to_string(), span.clone()))?;
|
||||||
|
|
||||||
FieldType::Constant(constant_inverse)
|
FieldType::Constant(constant_inverse)
|
||||||
}
|
}
|
||||||
FieldType::Allocated(allocated) => {
|
FieldType::Allocated(allocated) => {
|
||||||
let allocated_inverse = allocated
|
let allocated_inverse = allocated
|
||||||
.inverse(&mut cs)
|
.inverse(&mut cs)
|
||||||
.map_err(|e| FieldError::binary_operation(format!("+"), e, span.clone()))?;
|
.map_err(|e| FieldError::binary_operation("+".to_string(), e, span.clone()))?;
|
||||||
|
|
||||||
FieldType::Allocated(allocated_inverse)
|
FieldType::Allocated(allocated_inverse)
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ use std::{
|
|||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum EdwardsGroupType {
|
pub enum EdwardsGroupType {
|
||||||
Constant(EdwardsAffine),
|
Constant(EdwardsAffine),
|
||||||
Allocated(EdwardsBlsGadget),
|
Allocated(Box<EdwardsBlsGadget>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GroupType<Fq> for EdwardsGroupType {
|
impl GroupType<Fq> for EdwardsGroupType {
|
||||||
@ -60,7 +60,7 @@ impl GroupType<Fq> for EdwardsGroupType {
|
|||||||
|
|
||||||
fn to_allocated<CS: ConstraintSystem<Fq>>(&self, mut cs: CS, span: Span) -> Result<Self, GroupError> {
|
fn to_allocated<CS: ConstraintSystem<Fq>>(&self, mut cs: CS, span: Span) -> Result<Self, GroupError> {
|
||||||
self.allocated(cs.ns(|| format!("allocate affine point {}:{}", span.line, span.start)))
|
self.allocated(cs.ns(|| format!("allocate affine point {}:{}", span.line, span.start)))
|
||||||
.map(|result| EdwardsGroupType::Allocated(result))
|
.map(|ebg| EdwardsGroupType::Allocated(Box::new(ebg)))
|
||||||
.map_err(|error| GroupError::synthesis_error(error, span))
|
.map_err(|error| GroupError::synthesis_error(error, span))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ impl GroupType<Fq> for EdwardsGroupType {
|
|||||||
let result = <EdwardsBlsGadget as GroupGadget<GroupAffine<EdwardsParameters>, Fq>>::negate(group, cs)
|
let result = <EdwardsBlsGadget as GroupGadget<GroupAffine<EdwardsParameters>, Fq>>::negate(group, cs)
|
||||||
.map_err(|e| GroupError::negate_operation(e, span))?;
|
.map_err(|e| GroupError::negate_operation(e, span))?;
|
||||||
|
|
||||||
Ok(EdwardsGroupType::Allocated(result))
|
Ok(EdwardsGroupType::Allocated(Box::new(result)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -88,18 +88,18 @@ impl GroupType<Fq> for EdwardsGroupType {
|
|||||||
cs,
|
cs,
|
||||||
other_value,
|
other_value,
|
||||||
)
|
)
|
||||||
.map_err(|e| GroupError::binary_operation(format!("+"), e, span))?;
|
.map_err(|e| GroupError::binary_operation("+".to_string(), e, span))?;
|
||||||
|
|
||||||
Ok(EdwardsGroupType::Allocated(result))
|
Ok(EdwardsGroupType::Allocated(Box::new(result)))
|
||||||
}
|
}
|
||||||
|
|
||||||
(EdwardsGroupType::Constant(constant_value), EdwardsGroupType::Allocated(allocated_value))
|
(EdwardsGroupType::Constant(constant_value), EdwardsGroupType::Allocated(allocated_value))
|
||||||
| (EdwardsGroupType::Allocated(allocated_value), EdwardsGroupType::Constant(constant_value)) => {
|
| (EdwardsGroupType::Allocated(allocated_value), EdwardsGroupType::Constant(constant_value)) => {
|
||||||
Ok(EdwardsGroupType::Allocated(
|
Ok(EdwardsGroupType::Allocated(Box::new(
|
||||||
allocated_value
|
allocated_value
|
||||||
.add_constant(cs, constant_value)
|
.add_constant(cs, constant_value)
|
||||||
.map_err(|e| GroupError::binary_operation(format!("+"), e, span))?,
|
.map_err(|e| GroupError::binary_operation("+".to_string(), e, span))?,
|
||||||
))
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -116,18 +116,18 @@ impl GroupType<Fq> for EdwardsGroupType {
|
|||||||
cs,
|
cs,
|
||||||
other_value,
|
other_value,
|
||||||
)
|
)
|
||||||
.map_err(|e| GroupError::binary_operation(format!("-"), e, span))?;
|
.map_err(|e| GroupError::binary_operation("-".to_string(), e, span))?;
|
||||||
|
|
||||||
Ok(EdwardsGroupType::Allocated(result))
|
Ok(EdwardsGroupType::Allocated(Box::new(result)))
|
||||||
}
|
}
|
||||||
|
|
||||||
(EdwardsGroupType::Constant(constant_value), EdwardsGroupType::Allocated(allocated_value))
|
(EdwardsGroupType::Constant(constant_value), EdwardsGroupType::Allocated(allocated_value))
|
||||||
| (EdwardsGroupType::Allocated(allocated_value), EdwardsGroupType::Constant(constant_value)) => {
|
| (EdwardsGroupType::Allocated(allocated_value), EdwardsGroupType::Constant(constant_value)) => {
|
||||||
Ok(EdwardsGroupType::Allocated(
|
Ok(EdwardsGroupType::Allocated(Box::new(
|
||||||
allocated_value
|
allocated_value
|
||||||
.sub_constant(cs, constant_value)
|
.sub_constant(cs, constant_value)
|
||||||
.map_err(|e| GroupError::binary_operation(format!("-"), e, span))?,
|
.map_err(|e| GroupError::binary_operation("-".to_string(), e, span))?,
|
||||||
))
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -143,13 +143,13 @@ impl EdwardsGroupType {
|
|||||||
|
|
||||||
pub fn edwards_affine_from_single(number: String, span: Span) -> Result<EdwardsAffine, GroupError> {
|
pub fn edwards_affine_from_single(number: String, span: Span) -> Result<EdwardsAffine, GroupError> {
|
||||||
if number.eq("0") {
|
if number.eq("0") {
|
||||||
return Ok(EdwardsAffine::zero());
|
Ok(EdwardsAffine::zero())
|
||||||
} else {
|
} else {
|
||||||
let one = edwards_affine_one();
|
let one = edwards_affine_one();
|
||||||
let number_value = Fp256::from_str(&number).map_err(|_| GroupError::n_group(number, span))?;
|
let number_value = Fp256::from_str(&number).map_err(|_| GroupError::n_group(number, span))?;
|
||||||
let result: EdwardsAffine = one.mul(&number_value);
|
let result: EdwardsAffine = one.mul(&number_value);
|
||||||
|
|
||||||
return Ok(result);
|
Ok(result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,11 +201,13 @@ impl EdwardsGroupType {
|
|||||||
let x = Fq::from_str(&x_string).map_err(|_| GroupError::x_invalid(x_string, x_span))?;
|
let x = Fq::from_str(&x_string).map_err(|_| GroupError::x_invalid(x_string, x_span))?;
|
||||||
match greatest {
|
match greatest {
|
||||||
// Sign provided
|
// Sign provided
|
||||||
Some(greatest) => EdwardsAffine::from_x_coordinate(x, greatest).ok_or(GroupError::x_recover(element_span)),
|
Some(greatest) => {
|
||||||
|
EdwardsAffine::from_x_coordinate(x, greatest).ok_or_else(|| GroupError::x_recover(element_span))
|
||||||
|
}
|
||||||
// Sign inferred
|
// Sign inferred
|
||||||
None => {
|
None => {
|
||||||
// Attempt to recover with a sign_low bit.
|
// Attempt to recover with a sign_low bit.
|
||||||
if let Some(element) = EdwardsAffine::from_x_coordinate(x.clone(), false) {
|
if let Some(element) = EdwardsAffine::from_x_coordinate(x, false) {
|
||||||
return Ok(element);
|
return Ok(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,11 +232,13 @@ impl EdwardsGroupType {
|
|||||||
|
|
||||||
match greatest {
|
match greatest {
|
||||||
// Sign provided
|
// Sign provided
|
||||||
Some(greatest) => EdwardsAffine::from_y_coordinate(y, greatest).ok_or(GroupError::y_recover(element_span)),
|
Some(greatest) => {
|
||||||
|
EdwardsAffine::from_y_coordinate(y, greatest).ok_or_else(|| GroupError::y_recover(element_span))
|
||||||
|
}
|
||||||
// Sign inferred
|
// Sign inferred
|
||||||
None => {
|
None => {
|
||||||
// Attempt to recover with a sign_low bit.
|
// Attempt to recover with a sign_low bit.
|
||||||
if let Some(element) = EdwardsAffine::from_y_coordinate(y.clone(), false) {
|
if let Some(element) = EdwardsAffine::from_y_coordinate(y, false) {
|
||||||
return Ok(element);
|
return Ok(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,12 +298,8 @@ impl EdwardsGroupType {
|
|||||||
let x_value = allocated.x.get_value();
|
let x_value = allocated.x.get_value();
|
||||||
let y_value = allocated.y.get_value();
|
let y_value = allocated.y.get_value();
|
||||||
|
|
||||||
let x_allocated = FpGadget::alloc(cs.ns(|| format!("x")), || {
|
let x_allocated = FpGadget::alloc(cs.ns(|| "x"), || x_value.ok_or(SynthesisError::AssignmentMissing))?;
|
||||||
x_value.ok_or(SynthesisError::AssignmentMissing)
|
let y_allocated = FpGadget::alloc(cs.ns(|| "y"), || y_value.ok_or(SynthesisError::AssignmentMissing))?;
|
||||||
})?;
|
|
||||||
let y_allocated = FpGadget::alloc(cs.ns(|| format!("y")), || {
|
|
||||||
y_value.ok_or(SynthesisError::AssignmentMissing)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(EdwardsBlsGadget::new(x_allocated, y_allocated))
|
Ok(EdwardsBlsGadget::new(x_allocated, y_allocated))
|
||||||
}
|
}
|
||||||
@ -316,7 +316,7 @@ impl AllocGadget<GroupValue, Fq> for EdwardsGroupType {
|
|||||||
Self::alloc_helper(value_gen)
|
Self::alloc_helper(value_gen)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok(EdwardsGroupType::Allocated(value))
|
Ok(EdwardsGroupType::Allocated(Box::new(value)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn alloc_input<Fn: FnOnce() -> Result<T, SynthesisError>, T: Borrow<GroupValue>, CS: ConstraintSystem<Fq>>(
|
fn alloc_input<Fn: FnOnce() -> Result<T, SynthesisError>, T: Borrow<GroupValue>, CS: ConstraintSystem<Fq>>(
|
||||||
@ -327,7 +327,7 @@ impl AllocGadget<GroupValue, Fq> for EdwardsGroupType {
|
|||||||
Self::alloc_helper(value_gen)
|
Self::alloc_helper(value_gen)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok(EdwardsGroupType::Allocated(value))
|
Ok(EdwardsGroupType::Allocated(Box::new(value)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -454,7 +454,7 @@ impl CondSelectGadget<Fq> for EdwardsGroupType {
|
|||||||
let second_gadget = second.allocated(cs.ns(|| "second"))?;
|
let second_gadget = second.allocated(cs.ns(|| "second"))?;
|
||||||
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))
|
Ok(EdwardsGroupType::Allocated(Box::new(result)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +157,7 @@ impl Integer {
|
|||||||
let unsigned_integer = self;
|
let unsigned_integer = self;
|
||||||
let value_option: Option<String> = match_unsigned_integer!(unsigned_integer => unsigned_integer.get_value());
|
let value_option: Option<String> = match_unsigned_integer!(unsigned_integer => unsigned_integer.get_value());
|
||||||
|
|
||||||
let value = value_option.ok_or(IntegerError::invalid_index(span.clone()))?;
|
let value = value_option.ok_or_else(|| IntegerError::invalid_index(span.clone()))?;
|
||||||
let value_usize = value
|
let value_usize = value
|
||||||
.parse::<usize>()
|
.parse::<usize>()
|
||||||
.map_err(|_| IntegerError::invalid_integer(value, span))?;
|
.map_err(|_| IntegerError::invalid_integer(value, span))?;
|
||||||
@ -378,7 +378,7 @@ impl Integer {
|
|||||||
|
|
||||||
let result = match_signed_integer!(a, s => a.neg(cs.ns(|| unique_namespace)));
|
let result = match_signed_integer!(a, s => a.neg(cs.ns(|| unique_namespace)));
|
||||||
|
|
||||||
result.ok_or(IntegerError::negate_operation(span))
|
result.ok_or_else(|| IntegerError::negate_operation(span))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add<F: Field + PrimeField, CS: ConstraintSystem<F>>(
|
pub fn add<F: Field + PrimeField, CS: ConstraintSystem<F>>(
|
||||||
@ -395,7 +395,7 @@ impl Integer {
|
|||||||
|
|
||||||
let result = match_integers_span!((a, b), s => a.add(cs.ns(|| unique_namespace), &b));
|
let result = match_integers_span!((a, b), s => a.add(cs.ns(|| unique_namespace), &b));
|
||||||
|
|
||||||
result.ok_or(IntegerError::binary_operation(format!("+"), span))
|
result.ok_or_else(|| IntegerError::binary_operation("+".to_string(), span))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sub<F: Field + PrimeField, CS: ConstraintSystem<F>>(
|
pub fn sub<F: Field + PrimeField, CS: ConstraintSystem<F>>(
|
||||||
@ -412,7 +412,7 @@ impl Integer {
|
|||||||
|
|
||||||
let result = match_integers_span!((a, b), s => a.sub(cs.ns(|| unique_namespace), &b));
|
let result = match_integers_span!((a, b), s => a.sub(cs.ns(|| unique_namespace), &b));
|
||||||
|
|
||||||
result.ok_or(IntegerError::binary_operation(format!("-"), span))
|
result.ok_or_else(|| IntegerError::binary_operation("-".to_string(), span))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mul<F: Field + PrimeField, CS: ConstraintSystem<F>>(
|
pub fn mul<F: Field + PrimeField, CS: ConstraintSystem<F>>(
|
||||||
@ -429,7 +429,7 @@ impl Integer {
|
|||||||
|
|
||||||
let result = match_integers_span!((a, b), s => a.mul(cs.ns(|| unique_namespace), &b));
|
let result = match_integers_span!((a, b), s => a.mul(cs.ns(|| unique_namespace), &b));
|
||||||
|
|
||||||
result.ok_or(IntegerError::binary_operation(format!("*"), span))
|
result.ok_or_else(|| IntegerError::binary_operation("*".to_string(), span))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn div<F: Field + PrimeField, CS: ConstraintSystem<F>>(
|
pub fn div<F: Field + PrimeField, CS: ConstraintSystem<F>>(
|
||||||
@ -446,7 +446,7 @@ impl Integer {
|
|||||||
|
|
||||||
let result = match_integers_span!((a, b), s => a.div(cs.ns(|| unique_namespace), &b));
|
let result = match_integers_span!((a, b), s => a.div(cs.ns(|| unique_namespace), &b));
|
||||||
|
|
||||||
result.ok_or(IntegerError::binary_operation(format!("÷"), span))
|
result.ok_or_else(|| IntegerError::binary_operation("÷".to_string(), span))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pow<F: Field + PrimeField, CS: ConstraintSystem<F>>(
|
pub fn pow<F: Field + PrimeField, CS: ConstraintSystem<F>>(
|
||||||
@ -463,7 +463,7 @@ impl Integer {
|
|||||||
|
|
||||||
let result = match_integers_span!((a, b), s => a.pow(cs.ns(|| unique_namespace), &b));
|
let result = match_integers_span!((a, b), s => a.pow(cs.ns(|| unique_namespace), &b));
|
||||||
|
|
||||||
result.ok_or(IntegerError::binary_operation(format!("**"), span))
|
result.ok_or_else(|| IntegerError::binary_operation("**".to_string(), span))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
|
|||||||
|
|
||||||
// Data type wrappers
|
// Data type wrappers
|
||||||
ConstrainedValue::Array(array) => {
|
ConstrainedValue::Array(array) => {
|
||||||
let array_type = array[0].to_type(span.clone())?;
|
let array_type = array[0].to_type(span)?;
|
||||||
let mut dimensions = vec![array.len()];
|
let mut dimensions = vec![array.len()];
|
||||||
|
|
||||||
// Nested array type
|
// Nested array type
|
||||||
@ -205,15 +205,15 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
|
|||||||
// If this is a circuit function, evaluate inside the circuit scope
|
// If this is a circuit function, evaluate inside the circuit scope
|
||||||
if let Some(identifier) = circuit_identifier {
|
if let Some(identifier) = circuit_identifier {
|
||||||
// avoid creating recursive scope
|
// avoid creating recursive scope
|
||||||
if !is_in_scope(&scope, &identifier.name.to_string()) {
|
if !is_in_scope(&scope, &identifier.name) {
|
||||||
outer_scope = new_scope(scope, identifier.name.to_string());
|
outer_scope = new_scope(scope, identifier.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok((outer_scope, function.clone()))
|
Ok((outer_scope, function))
|
||||||
}
|
}
|
||||||
ConstrainedValue::Import(import_scope, function) => function.extract_function(import_scope, span),
|
ConstrainedValue::Import(import_scope, function) => function.extract_function(import_scope, span),
|
||||||
value => return Err(ExpressionError::undefined_function(value.to_string(), span)),
|
value => Err(ExpressionError::undefined_function(value.to_string(), span)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,7 +221,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
|
|||||||
match self {
|
match self {
|
||||||
ConstrainedValue::CircuitDefinition(circuit) => Ok(circuit),
|
ConstrainedValue::CircuitDefinition(circuit) => Ok(circuit),
|
||||||
ConstrainedValue::Import(_import_scope, circuit) => circuit.extract_circuit(span),
|
ConstrainedValue::Import(_import_scope, circuit) => circuit.extract_circuit(span),
|
||||||
value => return Err(ExpressionError::undefined_circuit(value.to_string(), span)),
|
value => Err(ExpressionError::undefined_circuit(value.to_string(), span)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,7 +239,9 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
|
|||||||
}
|
}
|
||||||
ConstrainedValue::Boolean(boolean) => {
|
ConstrainedValue::Boolean(boolean) => {
|
||||||
let option = boolean.get_value();
|
let option = boolean.get_value();
|
||||||
let name = option.map(|b| b.to_string()).unwrap_or(format!("[allocated]"));
|
let name = option
|
||||||
|
.map(|b| b.to_string())
|
||||||
|
.unwrap_or_else(|| "[allocated]".to_string());
|
||||||
|
|
||||||
*boolean = allocate_bool(&mut cs, name, option, span)?;
|
*boolean = allocate_bool(&mut cs, name, option, span)?;
|
||||||
}
|
}
|
||||||
@ -256,7 +258,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
|
|||||||
ConstrainedValue::Integer(integer) => {
|
ConstrainedValue::Integer(integer) => {
|
||||||
let integer_type = integer.get_type();
|
let integer_type = integer.get_type();
|
||||||
let option = integer.get_value();
|
let option = integer.get_value();
|
||||||
let name = option.clone().unwrap_or(format!("[allocated]"));
|
let name = option.clone().unwrap_or_else(|| "[allocated]".to_string());
|
||||||
|
|
||||||
*integer = Integer::allocate_type(&mut cs, integer_type, name, option, span)?;
|
*integer = Integer::allocate_type(&mut cs, integer_type, name, option, span)?;
|
||||||
}
|
}
|
||||||
@ -328,7 +330,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> fmt::Display for ConstrainedValue<F
|
|||||||
value
|
value
|
||||||
.get_value()
|
.get_value()
|
||||||
.map(|v| v.to_string())
|
.map(|v| v.to_string())
|
||||||
.unwrap_or(format!("[allocated]"))
|
.unwrap_or_else(|| "[allocated]".to_string())
|
||||||
),
|
),
|
||||||
ConstrainedValue::Field(ref value) => write!(f, "{:?}", value),
|
ConstrainedValue::Field(ref value) => write!(f, "{:?}", value),
|
||||||
ConstrainedValue::Group(ref value) => write!(f, "{:?}", value),
|
ConstrainedValue::Group(ref value) => write!(f, "{:?}", value),
|
||||||
@ -402,18 +404,18 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConditionalEqGadget<F> for Constrai
|
|||||||
num_1.conditional_enforce_equal(cs, num_2, condition)
|
num_1.conditional_enforce_equal(cs, num_2, condition)
|
||||||
}
|
}
|
||||||
(ConstrainedValue::Array(arr_1), ConstrainedValue::Array(arr_2)) => {
|
(ConstrainedValue::Array(arr_1), ConstrainedValue::Array(arr_2)) => {
|
||||||
for (i, (left, right)) in arr_1.into_iter().zip(arr_2.into_iter()).enumerate() {
|
for (i, (left, right)) in arr_1.iter().zip(arr_2.iter()).enumerate() {
|
||||||
left.conditional_enforce_equal(cs.ns(|| format!("array[{}]", i)), right, condition)?;
|
left.conditional_enforce_equal(cs.ns(|| format!("array[{}]", i)), right, condition)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
(ConstrainedValue::Tuple(tuple_1), ConstrainedValue::Tuple(tuple_2)) => {
|
(ConstrainedValue::Tuple(tuple_1), ConstrainedValue::Tuple(tuple_2)) => {
|
||||||
for (i, (left, right)) in tuple_1.into_iter().zip(tuple_2.into_iter()).enumerate() {
|
for (i, (left, right)) in tuple_1.iter().zip(tuple_2.iter()).enumerate() {
|
||||||
left.conditional_enforce_equal(cs.ns(|| format!("tuple index {}", i)), right, condition)?;
|
left.conditional_enforce_equal(cs.ns(|| format!("tuple index {}", i)), right, condition)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
(_, _) => return Err(SynthesisError::Unsatisfiable),
|
(_, _) => Err(SynthesisError::Unsatisfiable),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -448,7 +450,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> CondSelectGadget<F> for Constrained
|
|||||||
(ConstrainedValue::Array(arr_1), ConstrainedValue::Array(arr_2)) => {
|
(ConstrainedValue::Array(arr_1), ConstrainedValue::Array(arr_2)) => {
|
||||||
let mut array = vec![];
|
let mut array = vec![];
|
||||||
|
|
||||||
for (i, (first, second)) in arr_1.into_iter().zip(arr_2.into_iter()).enumerate() {
|
for (i, (first, second)) in arr_1.iter().zip(arr_2.iter()).enumerate() {
|
||||||
array.push(Self::conditionally_select(
|
array.push(Self::conditionally_select(
|
||||||
cs.ns(|| format!("array[{}]", i)),
|
cs.ns(|| format!("array[{}]", i)),
|
||||||
cond,
|
cond,
|
||||||
@ -462,7 +464,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> CondSelectGadget<F> for Constrained
|
|||||||
(ConstrainedValue::Tuple(tuple_1), ConstrainedValue::Array(tuple_2)) => {
|
(ConstrainedValue::Tuple(tuple_1), ConstrainedValue::Array(tuple_2)) => {
|
||||||
let mut array = vec![];
|
let mut array = vec![];
|
||||||
|
|
||||||
for (i, (first, second)) in tuple_1.into_iter().zip(tuple_2.into_iter()).enumerate() {
|
for (i, (first, second)) in tuple_1.iter().zip(tuple_2.iter()).enumerate() {
|
||||||
array.push(Self::conditionally_select(
|
array.push(Self::conditionally_select(
|
||||||
cs.ns(|| format!("tuple index {}", i)),
|
cs.ns(|| format!("tuple index {}", i)),
|
||||||
cond,
|
cond,
|
||||||
@ -484,7 +486,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> CondSelectGadget<F> for Constrained
|
|||||||
) => {
|
) => {
|
||||||
let mut members = vec![];
|
let mut members = vec![];
|
||||||
|
|
||||||
for (i, (first, second)) in members_1.into_iter().zip(members_2.into_iter()).enumerate() {
|
for (i, (first, second)) in members_1.iter().zip(members_2.iter()).enumerate() {
|
||||||
members.push(ConstrainedCircuitMember::conditionally_select(
|
members.push(ConstrainedCircuitMember::conditionally_select(
|
||||||
cs.ns(|| format!("circuit member[{}]", i)),
|
cs.ns(|| format!("circuit member[{}]", i)),
|
||||||
cond,
|
cond,
|
||||||
@ -545,18 +547,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> From<Value> for ConstrainedValue<F,
|
|||||||
Value::I64(i64) => ConstrainedValue::Integer(Integer::I64(i64)),
|
Value::I64(i64) => ConstrainedValue::Integer(Integer::I64(i64)),
|
||||||
Value::I128(i128) => ConstrainedValue::Integer(Integer::I128(i128)),
|
Value::I128(i128) => ConstrainedValue::Integer(Integer::I128(i128)),
|
||||||
|
|
||||||
Value::Array(array) => ConstrainedValue::Array(
|
Value::Array(array) => ConstrainedValue::Array(array.into_iter().map(ConstrainedValue::from).collect()),
|
||||||
array
|
Value::Tuple(tuple) => ConstrainedValue::Tuple(tuple.into_iter().map(ConstrainedValue::from).collect()),
|
||||||
.into_iter()
|
|
||||||
.map(|element| ConstrainedValue::from(element))
|
|
||||||
.collect(),
|
|
||||||
),
|
|
||||||
Value::Tuple(tuple) => ConstrainedValue::Tuple(
|
|
||||||
tuple
|
|
||||||
.into_iter()
|
|
||||||
.map(|element| ConstrainedValue::from(element))
|
|
||||||
.collect(),
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ impl CorePackageError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn core_package_star(span: Span) -> Self {
|
pub fn core_package_star(span: Span) -> Self {
|
||||||
let message = format!("Cannot import star from leo-core");
|
let message = "Cannot import star from leo-core".to_string();
|
||||||
|
|
||||||
Self::new_from_span(message, span)
|
Self::new_from_span(message, span)
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ impl CorePackageListError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn core_package_star(span: Span) -> Self {
|
pub fn core_package_star(span: Span) -> Self {
|
||||||
let message = format!("Cannot import star from leo-core");
|
let message = "Cannot import star from leo-core".to_string();
|
||||||
|
|
||||||
Self::new_from_span(message, span)
|
Self::new_from_span(message, span)
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,7 @@ impl CoreCircuit for Blake2sCircuit {
|
|||||||
),
|
),
|
||||||
span.clone(),
|
span.clone(),
|
||||||
)],
|
)],
|
||||||
span: span.clone(),
|
span,
|
||||||
},
|
},
|
||||||
)],
|
)],
|
||||||
}
|
}
|
||||||
@ -141,7 +141,7 @@ impl CoreCircuit for Blake2sCircuit {
|
|||||||
.to_bytes(cs)
|
.to_bytes(cs)
|
||||||
.map_err(|e| CoreCircuitError::cannot_enforce("Vec<UInt8> ToBytes".to_owned(), e, span.clone()))?;
|
.map_err(|e| CoreCircuitError::cannot_enforce("Vec<UInt8> ToBytes".to_owned(), e, span.clone()))?;
|
||||||
|
|
||||||
let return_value = bytes.into_iter().map(|byte| Value::U8(byte)).collect();
|
let return_value = bytes.into_iter().map(Value::U8).collect();
|
||||||
|
|
||||||
// Return one array digest value
|
// Return one array digest value
|
||||||
Ok(vec![Value::Array(return_value)])
|
Ok(vec![Value::Array(return_value)])
|
||||||
|
@ -71,7 +71,7 @@ impl CorePackage {
|
|||||||
let span = circuit.span.clone();
|
let span = circuit.span.clone();
|
||||||
|
|
||||||
// take the alias if it is present
|
// take the alias if it is present
|
||||||
let id = circuit.alias.clone().unwrap_or(circuit.symbol.clone());
|
let id = circuit.alias.clone().unwrap_or_else(|| circuit.symbol.clone());
|
||||||
let name = id.name.clone();
|
let name = id.name.clone();
|
||||||
|
|
||||||
let circuit = if self.unstable {
|
let circuit = if self.unstable {
|
||||||
@ -87,9 +87,7 @@ impl CorePackage {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// match core circuit
|
// match core circuit
|
||||||
match circuit_name {
|
return Err(CorePackageError::undefined_core_circuit(circuit_name.to_string(), span));
|
||||||
name => return Err(CorePackageError::undefined_core_circuit(name.to_string(), span)),
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
circuit_structs.push(name, circuit)
|
circuit_structs.push(name, circuit)
|
||||||
|
@ -71,7 +71,7 @@ impl fmt::Display for Value {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let string = string_option.unwrap_or("[input]".to_owned());
|
let string = string_option.unwrap_or_else(|| "[input]".to_owned());
|
||||||
|
|
||||||
write!(f, "{}", string)
|
write!(f, "{}", string)
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,6 @@ where
|
|||||||
{
|
{
|
||||||
type ErrorType;
|
type ErrorType;
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
fn add<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Self, Self::ErrorType>;
|
fn add<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Self, Self::ErrorType>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,5 @@ where
|
|||||||
{
|
{
|
||||||
type ErrorType;
|
type ErrorType;
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
fn div<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Self, Self::ErrorType>;
|
fn div<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Self, Self::ErrorType>;
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,5 @@ where
|
|||||||
{
|
{
|
||||||
type ErrorType;
|
type ErrorType;
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
fn mul<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Self, Self::ErrorType>;
|
fn mul<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Self, Self::ErrorType>;
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,6 @@ where
|
|||||||
{
|
{
|
||||||
type ErrorType;
|
type ErrorType;
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
fn neg<CS: ConstraintSystem<F>>(&self, cs: CS) -> Result<Self, Self::ErrorType>;
|
fn neg<CS: ConstraintSystem<F>>(&self, cs: CS) -> Result<Self, Self::ErrorType>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,7 +43,7 @@ impl<F: Field> Neg<F> for Vec<Boolean> {
|
|||||||
let mut one = vec![Boolean::constant(true)];
|
let mut one = vec![Boolean::constant(true)];
|
||||||
one.append(&mut vec![Boolean::Constant(false); self.len() - 1]);
|
one.append(&mut vec![Boolean::Constant(false); self.len() - 1]);
|
||||||
|
|
||||||
let mut bits = flipped.add_bits(cs.ns(|| format!("add one")), &one)?;
|
let mut bits = flipped.add_bits(cs.ns(|| "add one"), &one)?;
|
||||||
let _carry = bits.pop(); // we already accounted for overflow above
|
let _carry = bits.pop(); // we already accounted for overflow above
|
||||||
|
|
||||||
Ok(bits)
|
Ok(bits)
|
||||||
|
@ -23,6 +23,5 @@ where
|
|||||||
{
|
{
|
||||||
type ErrorType;
|
type ErrorType;
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
fn pow<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Self, Self::ErrorType>;
|
fn pow<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Self, Self::ErrorType>;
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,5 @@ where
|
|||||||
{
|
{
|
||||||
type ErrorType;
|
type ErrorType;
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
fn sub<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Self, Self::ErrorType>;
|
fn sub<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Self, Self::ErrorType>;
|
||||||
}
|
}
|
||||||
|
@ -44,12 +44,12 @@ impl<'a, F: Field> FullAdder<'a, F> for Boolean {
|
|||||||
b: &'a Self,
|
b: &'a Self,
|
||||||
carry: &'a Self,
|
carry: &'a Self,
|
||||||
) -> Result<(Self, Self), SynthesisError> {
|
) -> Result<(Self, Self), SynthesisError> {
|
||||||
let a_x_b = Boolean::xor(cs.ns(|| format!("a XOR b")), a, b)?;
|
let a_x_b = Boolean::xor(cs.ns(|| "a XOR b"), a, b)?;
|
||||||
let sum = Boolean::xor(cs.ns(|| format!("adder sum")), &a_x_b, carry)?;
|
let sum = Boolean::xor(cs.ns(|| "adder sum"), &a_x_b, carry)?;
|
||||||
|
|
||||||
let c1 = Boolean::and(cs.ns(|| format!("a AND b")), a, b)?;
|
let c1 = Boolean::and(cs.ns(|| "a AND b"), a, b)?;
|
||||||
let c2 = Boolean::and(cs.ns(|| format!("carry AND (a XOR b)")), carry, &a_x_b)?;
|
let c2 = Boolean::and(cs.ns(|| "carry AND (a XOR b)"), carry, &a_x_b)?;
|
||||||
let carry = Boolean::or(cs.ns(|| format!("c1 OR c2")), &c1, &c2)?;
|
let carry = Boolean::or(cs.ns(|| "c1 OR c2"), &c1, &c2)?;
|
||||||
|
|
||||||
Ok((sum, carry))
|
Ok((sum, carry))
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,6 @@ pub trait RippleCarryAdder<F: Field, Rhs = Self>
|
|||||||
where
|
where
|
||||||
Self: std::marker::Sized,
|
Self: std::marker::Sized,
|
||||||
{
|
{
|
||||||
#[must_use]
|
|
||||||
fn add_bits<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Vec<Boolean>, SynthesisError>;
|
fn add_bits<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Vec<Boolean>, SynthesisError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ impl SignExtend for Boolean {
|
|||||||
fn sign_extend(bits: &[Boolean], length: usize) -> Vec<Boolean> {
|
fn sign_extend(bits: &[Boolean], length: usize) -> Vec<Boolean> {
|
||||||
let msb = bits.last().expect("empty bit list");
|
let msb = bits.last().expect("empty bit list");
|
||||||
let bits_needed = length - bits.len();
|
let bits_needed = length - bits.len();
|
||||||
let mut extension = vec![msb.clone(); bits_needed];
|
let mut extension = vec![*msb; bits_needed];
|
||||||
|
|
||||||
let mut result = Vec::from(bits);
|
let mut result = Vec::from(bits);
|
||||||
result.append(&mut extension);
|
result.append(&mut extension);
|
||||||
|
@ -87,7 +87,7 @@ macro_rules! add_int_impl {
|
|||||||
all_constants = false;
|
all_constants = false;
|
||||||
|
|
||||||
// Add the coeff * bit_gadget
|
// Add the coeff * bit_gadget
|
||||||
lc = lc + (coeff, bit.get_variable());
|
lc += (coeff, bit.get_variable());
|
||||||
}
|
}
|
||||||
Boolean::Not(ref bit) => {
|
Boolean::Not(ref bit) => {
|
||||||
all_constants = false;
|
all_constants = false;
|
||||||
@ -97,7 +97,7 @@ macro_rules! add_int_impl {
|
|||||||
}
|
}
|
||||||
Boolean::Constant(bit) => {
|
Boolean::Constant(bit) => {
|
||||||
if bit {
|
if bit {
|
||||||
lc = lc + (coeff, CS::one());
|
lc += (coeff, CS::one());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -206,13 +206,13 @@ macro_rules! div_int_impl {
|
|||||||
&r
|
&r
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
index = index - 1;
|
index -= 1;
|
||||||
|
|
||||||
let mut q_new = q.clone();
|
let mut q_new = q.clone();
|
||||||
q_new.bits[index] = true_bit.clone();
|
q_new.bits[index] = true_bit.clone();
|
||||||
q_new.value = Some(q_new.value.unwrap() + bit_value);
|
q_new.value = Some(q_new.value.unwrap() + bit_value);
|
||||||
|
|
||||||
bit_value = (bit_value >> 1);
|
bit_value >>= 1;
|
||||||
|
|
||||||
q = Self::conditionally_select(
|
q = Self::conditionally_select(
|
||||||
&mut cs.ns(|| format!("set_bit_or_same_{}", i)),
|
&mut cs.ns(|| format!("set_bit_or_same_{}", i)),
|
||||||
|
@ -146,7 +146,7 @@ macro_rules! mul_int_impl {
|
|||||||
all_constants = false;
|
all_constants = false;
|
||||||
|
|
||||||
// Add the coeff * bit_gadget
|
// Add the coeff * bit_gadget
|
||||||
lc = lc + (coeff, bit.get_variable());
|
lc += (coeff, bit.get_variable());
|
||||||
}
|
}
|
||||||
Boolean::Not(ref bit) => {
|
Boolean::Not(ref bit) => {
|
||||||
all_constants = false;
|
all_constants = false;
|
||||||
@ -156,7 +156,7 @@ macro_rules! mul_int_impl {
|
|||||||
}
|
}
|
||||||
Boolean::Constant(bit) => {
|
Boolean::Constant(bit) => {
|
||||||
if bit {
|
if bit {
|
||||||
lc = lc + (coeff, CS::one());
|
lc += (coeff, CS::one());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,20 +53,17 @@ pub enum InputParserError {
|
|||||||
|
|
||||||
impl InputParserError {
|
impl InputParserError {
|
||||||
pub fn set_path(&mut self, path: PathBuf) {
|
pub fn set_path(&mut self, path: PathBuf) {
|
||||||
match self {
|
if let InputParserError::SyntaxError(error) = self {
|
||||||
InputParserError::SyntaxError(error) => {
|
let new_error: Error<Rule> = match error {
|
||||||
let new_error: Error<Rule> = match error {
|
InputSyntaxError::Error(error) => {
|
||||||
InputSyntaxError::Error(error) => {
|
let new_error = error.clone();
|
||||||
let new_error = error.clone();
|
new_error.with_path(path.to_str().unwrap())
|
||||||
new_error.with_path(path.to_str().unwrap())
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
|
|
||||||
tracing::error!("{}", new_error);
|
tracing::error!("{}", new_error);
|
||||||
|
|
||||||
*error = InputSyntaxError::Error(new_error);
|
*error = InputSyntaxError::Error(new_error);
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ pub trait CLI {
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|a| {
|
.map(|a| {
|
||||||
let mut args = Arg::with_name(a.0).help(a.1).required(a.3).index(a.4);
|
let mut args = Arg::with_name(a.0).help(a.1).required(a.3).index(a.4);
|
||||||
if a.2.len() > 0 {
|
if !a.2.is_empty() {
|
||||||
args = args.possible_values(a.2);
|
args = args.possible_values(a.2);
|
||||||
}
|
}
|
||||||
args
|
args
|
||||||
@ -47,7 +47,7 @@ pub trait CLI {
|
|||||||
.collect::<Vec<Arg<'static, 'static>>>();
|
.collect::<Vec<Arg<'static, 'static>>>();
|
||||||
let options = &Self::OPTIONS
|
let options = &Self::OPTIONS
|
||||||
.iter()
|
.iter()
|
||||||
.map(|a| match a.2.len() > 0 {
|
.map(|a| match !a.2.is_empty() {
|
||||||
true => Arg::from_usage(a.0)
|
true => Arg::from_usage(a.0)
|
||||||
.conflicts_with_all(a.1)
|
.conflicts_with_all(a.1)
|
||||||
.possible_values(a.2)
|
.possible_values(a.2)
|
||||||
@ -64,7 +64,7 @@ pub trait CLI {
|
|||||||
&s.2.iter()
|
&s.2.iter()
|
||||||
.map(|a| {
|
.map(|a| {
|
||||||
let mut args = Arg::with_name(a.0).help(a.1).required(a.3).index(a.4);
|
let mut args = Arg::with_name(a.0).help(a.1).required(a.3).index(a.4);
|
||||||
if a.2.len() > 0 {
|
if !a.2.is_empty() {
|
||||||
args = args.possible_values(a.2);
|
args = args.possible_values(a.2);
|
||||||
}
|
}
|
||||||
args
|
args
|
||||||
@ -78,7 +78,7 @@ pub trait CLI {
|
|||||||
)
|
)
|
||||||
.args(
|
.args(
|
||||||
&s.4.iter()
|
&s.4.iter()
|
||||||
.map(|a| match a.2.len() > 0 {
|
.map(|a| match !a.2.is_empty() {
|
||||||
true => Arg::from_usage(a.0)
|
true => Arg::from_usage(a.0)
|
||||||
.conflicts_with_all(a.1)
|
.conflicts_with_all(a.1)
|
||||||
.possible_values(a.2)
|
.possible_values(a.2)
|
||||||
|
@ -167,7 +167,7 @@ impl CLI for AddCommand {
|
|||||||
let mut file_path = path.clone();
|
let mut file_path = path.clone();
|
||||||
file_path.push(file_name);
|
file_path.push(file_name);
|
||||||
|
|
||||||
if file_name.ends_with("/") {
|
if file_name.ends_with('/') {
|
||||||
create_dir_all(file_path)?;
|
create_dir_all(file_path)?;
|
||||||
} else {
|
} else {
|
||||||
if let Some(parent_directory) = path.parent() {
|
if let Some(parent_directory) = path.parent() {
|
||||||
|
@ -93,7 +93,7 @@ impl CLI for BuildCommand {
|
|||||||
// Compile the library file but do not output
|
// Compile the library file but do not output
|
||||||
let _program = Compiler::<Fq, EdwardsGroupType>::parse_program_without_input(
|
let _program = Compiler::<Fq, EdwardsGroupType>::parse_program_without_input(
|
||||||
package_name.clone(),
|
package_name.clone(),
|
||||||
lib_file_path.clone(),
|
lib_file_path,
|
||||||
output_directory.clone(),
|
output_directory.clone(),
|
||||||
)?;
|
)?;
|
||||||
tracing::info!("Complete");
|
tracing::info!("Complete");
|
||||||
@ -121,7 +121,7 @@ impl CLI for BuildCommand {
|
|||||||
// Load the program at `main_file_path`
|
// Load the program at `main_file_path`
|
||||||
let program = Compiler::<Fq, EdwardsGroupType>::parse_program_with_input(
|
let program = Compiler::<Fq, EdwardsGroupType>::parse_program_with_input(
|
||||||
package_name.clone(),
|
package_name.clone(),
|
||||||
main_file_path.clone(),
|
main_file_path,
|
||||||
output_directory,
|
output_directory,
|
||||||
&input_string,
|
&input_string,
|
||||||
input_path,
|
input_path,
|
||||||
|
@ -65,7 +65,7 @@ impl CLI for DeployCommand {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
let mut main_file_path = path.clone();
|
let mut main_file_path = path;
|
||||||
main_file_path.push(SOURCE_DIRECTORY_NAME);
|
main_file_path.push(SOURCE_DIRECTORY_NAME);
|
||||||
main_file_path.push(MAIN_FILENAME);
|
main_file_path.push(MAIN_FILENAME);
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ impl CLI for LintCommand {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
let mut main_file_path = path.clone();
|
let mut main_file_path = path;
|
||||||
main_file_path.push(SOURCE_DIRECTORY_NAME);
|
main_file_path.push(SOURCE_DIRECTORY_NAME);
|
||||||
main_file_path.push(MAIN_FILENAME);
|
main_file_path.push(MAIN_FILENAME);
|
||||||
|
|
||||||
|
@ -146,7 +146,7 @@ impl CLI for SetupCommand {
|
|||||||
Ok((program, proving_key, prepared_verifying_key))
|
Ok((program, proving_key, prepared_verifying_key))
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
let mut main_file_path = path.clone();
|
let mut main_file_path = path;
|
||||||
main_file_path.push(SOURCE_DIRECTORY_NAME);
|
main_file_path.push(SOURCE_DIRECTORY_NAME);
|
||||||
main_file_path.push(MAIN_FILENAME);
|
main_file_path.push(MAIN_FILENAME);
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ impl CLI for TestCommand {
|
|||||||
let package_name = manifest.get_package_name();
|
let package_name = manifest.get_package_name();
|
||||||
|
|
||||||
// Sanitize the package path to the root directory
|
// Sanitize the package path to the root directory
|
||||||
let mut package_path = path.clone();
|
let mut package_path = path;
|
||||||
if package_path.is_file() {
|
if package_path.is_file() {
|
||||||
package_path.pop();
|
package_path.pop();
|
||||||
}
|
}
|
||||||
@ -92,17 +92,14 @@ impl CLI for TestCommand {
|
|||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
|
|
||||||
// Parse the current main program file
|
// Parse the current main program file
|
||||||
let program = Compiler::<Fq, EdwardsGroupType>::parse_program_without_input(
|
let program =
|
||||||
package_name.clone(),
|
Compiler::<Fq, EdwardsGroupType>::parse_program_without_input(package_name, file_path, output_directory)?;
|
||||||
file_path.clone(),
|
|
||||||
output_directory,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
// Parse all inputs as input pairs
|
// Parse all inputs as input pairs
|
||||||
let pairs = InputPairs::try_from(&package_path)?;
|
let pairs = InputPairs::try_from(&package_path)?;
|
||||||
|
|
||||||
// Run tests
|
// Run tests
|
||||||
let temporary_program = program.clone();
|
let temporary_program = program;
|
||||||
let (passed, failed) = temporary_program.compile_test_constraints(pairs)?;
|
let (passed, failed) = temporary_program.compile_test_constraints(pairs)?;
|
||||||
|
|
||||||
// Drop "Test" context for console logging
|
// Drop "Test" context for console logging
|
||||||
|
@ -52,14 +52,11 @@ impl CLI for UpdateCommand {
|
|||||||
];
|
];
|
||||||
|
|
||||||
fn parse(arguments: &clap::ArgMatches) -> Result<Self::Options, crate::errors::CLIError> {
|
fn parse(arguments: &clap::ArgMatches) -> Result<Self::Options, crate::errors::CLIError> {
|
||||||
match arguments.subcommand() {
|
if let ("automatic", Some(arguments)) = arguments.subcommand() {
|
||||||
("automatic", Some(arguments)) => {
|
// Run the `automatic` subcommand
|
||||||
// Run the `automatic` subcommand
|
let options = UpdateAutomatic::parse(arguments)?;
|
||||||
let options = UpdateAutomatic::parse(arguments)?;
|
let _output = UpdateAutomatic::output(options)?;
|
||||||
let _output = UpdateAutomatic::output(options)?;
|
return Ok(None);
|
||||||
return Ok(None);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let show_all_versions = arguments.is_present("list");
|
let show_all_versions = arguments.is_present("list");
|
||||||
|
@ -57,8 +57,7 @@ impl CLI for WatchCommand {
|
|||||||
match rx.recv() {
|
match rx.recv() {
|
||||||
// See changes on the write event
|
// See changes on the write event
|
||||||
Ok(DebouncedEvent::Write(_write)) => {
|
Ok(DebouncedEvent::Write(_write)) => {
|
||||||
let options = ();
|
match BuildCommand::output(()) {
|
||||||
match BuildCommand::output(options) {
|
|
||||||
Ok(_output) => {
|
Ok(_output) => {
|
||||||
tracing::info!("Built successfully");
|
tracing::info!("Built successfully");
|
||||||
}
|
}
|
||||||
|
@ -91,7 +91,7 @@ impl Config {
|
|||||||
let toml_string = match fs::read_to_string(&config_path) {
|
let toml_string = match fs::read_to_string(&config_path) {
|
||||||
Ok(mut toml) => {
|
Ok(mut toml) => {
|
||||||
// If the config is using an incorrect format, rewrite it.
|
// If the config is using an incorrect format, rewrite it.
|
||||||
if let Err(_) = toml::from_str::<Config>(&toml) {
|
if toml::from_str::<Config>(&toml).is_err() {
|
||||||
let default_config_string = toml::to_string(&Config::default())?;
|
let default_config_string = toml::to_string(&Config::default())?;
|
||||||
fs::write(&config_path, default_config_string.clone())?;
|
fs::write(&config_path, default_config_string.clone())?;
|
||||||
toml = default_config_string;
|
toml = default_config_string;
|
||||||
@ -131,7 +131,7 @@ pub fn write_token(token: &str) -> Result<(), io::Error> {
|
|||||||
let config_dir = LEO_CONFIG_DIRECTORY.clone();
|
let config_dir = LEO_CONFIG_DIRECTORY.clone();
|
||||||
|
|
||||||
// Create Leo config directory if it not exists
|
// Create Leo config directory if it not exists
|
||||||
if !Path::new(&config_dir.to_path_buf()).exists() {
|
if !Path::new(&config_dir).exists() {
|
||||||
create_dir_all(&config_dir)?;
|
create_dir_all(&config_dir)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ impl<E: PairingEngine> From<CircuitSynthesizer<E>> for SerializedCircuit {
|
|||||||
let num_constraints = synthesizer.num_constraints();
|
let num_constraints = synthesizer.num_constraints();
|
||||||
|
|
||||||
// Serialize assignments
|
// Serialize assignments
|
||||||
fn get_serialized_assignments<E: PairingEngine>(assignments: &Vec<E::Fr>) -> Vec<SerializedField> {
|
fn get_serialized_assignments<E: PairingEngine>(assignments: &[E::Fr]) -> Vec<SerializedField> {
|
||||||
let mut serialized = vec![];
|
let mut serialized = vec![];
|
||||||
|
|
||||||
for assignment in assignments {
|
for assignment in assignments {
|
||||||
@ -74,7 +74,7 @@ impl<E: PairingEngine> From<CircuitSynthesizer<E>> for SerializedCircuit {
|
|||||||
|
|
||||||
// Serialize constraints
|
// Serialize constraints
|
||||||
fn get_serialized_constraints<E: PairingEngine>(
|
fn get_serialized_constraints<E: PairingEngine>(
|
||||||
constraints: &Vec<(E::Fr, Index)>,
|
constraints: &[(E::Fr, Index)],
|
||||||
) -> Vec<(SerializedField, SerializedIndex)> {
|
) -> Vec<(SerializedField, SerializedIndex)> {
|
||||||
let mut serialized = vec![];
|
let mut serialized = vec![];
|
||||||
|
|
||||||
@ -128,7 +128,7 @@ impl TryFrom<SerializedCircuit> for CircuitSynthesizer<Bls12_377> {
|
|||||||
fn try_from(serialized: SerializedCircuit) -> Result<CircuitSynthesizer<Bls12_377>, Self::Error> {
|
fn try_from(serialized: SerializedCircuit) -> Result<CircuitSynthesizer<Bls12_377>, Self::Error> {
|
||||||
// Deserialize assignments
|
// Deserialize assignments
|
||||||
fn get_deserialized_assignments(
|
fn get_deserialized_assignments(
|
||||||
assignments: &Vec<SerializedField>,
|
assignments: &[SerializedField],
|
||||||
) -> Result<Vec<<Bls12_377 as PairingEngine>::Fr>, FieldError> {
|
) -> Result<Vec<<Bls12_377 as PairingEngine>::Fr>, FieldError> {
|
||||||
let mut deserialized = vec![];
|
let mut deserialized = vec![];
|
||||||
|
|
||||||
@ -146,7 +146,7 @@ impl TryFrom<SerializedCircuit> for CircuitSynthesizer<Bls12_377> {
|
|||||||
|
|
||||||
// Deserialize constraints
|
// Deserialize constraints
|
||||||
fn get_deserialized_constraints(
|
fn get_deserialized_constraints(
|
||||||
constraints: &Vec<(SerializedField, SerializedIndex)>,
|
constraints: &[(SerializedField, SerializedIndex)],
|
||||||
) -> Result<Vec<(<Bls12_377 as PairingEngine>::Fr, Index)>, FieldError> {
|
) -> Result<Vec<(<Bls12_377 as PairingEngine>::Fr, Index)>, FieldError> {
|
||||||
let mut deserialized = vec![];
|
let mut deserialized = vec![];
|
||||||
|
|
||||||
|
@ -36,8 +36,8 @@ impl From<Index> for SerializedIndex {
|
|||||||
impl From<&SerializedIndex> for Index {
|
impl From<&SerializedIndex> for Index {
|
||||||
fn from(serialized_index: &SerializedIndex) -> Self {
|
fn from(serialized_index: &SerializedIndex) -> Self {
|
||||||
match serialized_index {
|
match serialized_index {
|
||||||
SerializedIndex::Input(idx) => Index::Input(idx.clone()),
|
SerializedIndex::Input(idx) => Index::Input(*idx),
|
||||||
SerializedIndex::Aux(idx) => Index::Aux(idx.clone()),
|
SerializedIndex::Aux(idx) => Index::Aux(*idx),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ use crate::{
|
|||||||
|
|
||||||
use std::{collections::HashMap, convert::TryFrom, path::PathBuf};
|
use std::{collections::HashMap, convert::TryFrom, path::PathBuf};
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
pub struct InputPairs {
|
pub struct InputPairs {
|
||||||
/// Maps file names to input file pairs
|
/// Maps file names to input file pairs
|
||||||
pub pairs: HashMap<String, InputPair>,
|
pub pairs: HashMap<String, InputPair>,
|
||||||
@ -33,7 +34,7 @@ pub struct InputPair {
|
|||||||
|
|
||||||
impl InputPairs {
|
impl InputPairs {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self { pairs: HashMap::new() }
|
Self::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,11 +53,11 @@ impl TryFrom<&PathBuf> for InputPairs {
|
|||||||
|
|
||||||
let file_name = file
|
let file_name = file
|
||||||
.file_stem()
|
.file_stem()
|
||||||
.ok_or(InputsDirectoryError::GettingFileName(file.as_os_str().to_owned()))?
|
.ok_or_else(|| InputsDirectoryError::GettingFileName(file.as_os_str().to_owned()))?
|
||||||
.to_str()
|
.to_str()
|
||||||
.ok_or(InputsDirectoryError::GettingFileName(file.as_os_str().to_owned()))?;
|
.ok_or_else(|| InputsDirectoryError::GettingFileName(file.as_os_str().to_owned()))?;
|
||||||
|
|
||||||
if file_extension == INPUT_FILE_EXTENSION.trim_start_matches(".") {
|
if file_extension == INPUT_FILE_EXTENSION.trim_start_matches('.') {
|
||||||
let input_file = InputFile::new(file_name).read_from(&file)?.0;
|
let input_file = InputFile::new(file_name).read_from(&file)?.0;
|
||||||
|
|
||||||
if pairs.contains_key(file_name) {
|
if pairs.contains_key(file_name) {
|
||||||
@ -69,7 +70,7 @@ impl TryFrom<&PathBuf> for InputPairs {
|
|||||||
};
|
};
|
||||||
pairs.insert(file_name.to_owned(), pair);
|
pairs.insert(file_name.to_owned(), pair);
|
||||||
}
|
}
|
||||||
} else if file_extension == STATE_FILE_EXTENSION.trim_start_matches(".") {
|
} else if file_extension == STATE_FILE_EXTENSION.trim_start_matches('.') {
|
||||||
let state_file = StateFile::new(file_name).read_from(&file)?.0;
|
let state_file = StateFile::new(file_name).read_from(&file)?.0;
|
||||||
|
|
||||||
if pairs.contains_key(file_name) {
|
if pairs.contains_key(file_name) {
|
||||||
|
@ -82,11 +82,11 @@ impl Package {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if existing_files.len() > 0 {
|
if !existing_files.is_empty() {
|
||||||
tracing::error!("File(s) {:?} already exist", existing_files);
|
tracing::error!("File(s) {:?} already exist", existing_files);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if a package is initialized at the given path
|
/// Returns `true` if a package is initialized at the given path
|
||||||
@ -120,7 +120,7 @@ impl Package {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a package at the given path
|
/// Creates a package at the given path
|
||||||
@ -128,9 +128,10 @@ impl Package {
|
|||||||
// First, verify that this directory is not already initialized as a Leo package.
|
// First, verify that this directory is not already initialized as a Leo package.
|
||||||
{
|
{
|
||||||
if !Self::can_initialize(package_name, is_lib, path) {
|
if !Self::can_initialize(package_name, is_lib, path) {
|
||||||
return Err(
|
return Err(PackageError::FailedToInitialize(
|
||||||
PackageError::FailedToInitialize(package_name.to_owned(), path.as_os_str().to_owned()).into(),
|
package_name.to_owned(),
|
||||||
);
|
path.as_os_str().to_owned(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Next, initialize this directory as a Leo package.
|
// Next, initialize this directory as a Leo package.
|
||||||
@ -174,9 +175,10 @@ impl Package {
|
|||||||
// Next, verify that a valid Leo package has been initialized in this directory
|
// Next, verify that a valid Leo package has been initialized in this directory
|
||||||
{
|
{
|
||||||
if !Self::is_initialized(package_name, is_lib, path) {
|
if !Self::is_initialized(package_name, is_lib, path) {
|
||||||
return Err(
|
return Err(PackageError::FailedToInitialize(
|
||||||
PackageError::FailedToInitialize(package_name.to_owned(), path.as_os_str().to_owned()).into(),
|
package_name.to_owned(),
|
||||||
);
|
path.as_os_str().to_owned(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,12 +23,12 @@ use std::{fs::File, io::Write, path::PathBuf};
|
|||||||
|
|
||||||
pub static GITIGNORE_FILENAME: &str = ".gitignore";
|
pub static GITIGNORE_FILENAME: &str = ".gitignore";
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize, Default)]
|
||||||
pub struct Gitignore;
|
pub struct Gitignore;
|
||||||
|
|
||||||
impl Gitignore {
|
impl Gitignore {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self
|
Self::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exists_at(path: &PathBuf) -> bool {
|
pub fn exists_at(path: &PathBuf) -> bool {
|
||||||
@ -50,9 +50,6 @@ impl Gitignore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn template(&self) -> String {
|
fn template(&self) -> String {
|
||||||
format!(
|
"outputs/\n".to_string()
|
||||||
r#"outputs/
|
|
||||||
"#,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -139,7 +139,7 @@ impl TryFrom<&PathBuf> for Manifest {
|
|||||||
// Determine if the old remote format is being used
|
// Determine if the old remote format is being used
|
||||||
if line.starts_with("remote") {
|
if line.starts_with("remote") {
|
||||||
let remote = line
|
let remote = line
|
||||||
.split("=") // Split the line as 'remote' = '"{author}/{package_name}"'
|
.split('=') // Split the line as 'remote' = '"{author}/{package_name}"'
|
||||||
.collect::<Vec<&str>>()[1]; // Fetch just '"{author}/{package_name}"'
|
.collect::<Vec<&str>>()[1]; // Fetch just '"{author}/{package_name}"'
|
||||||
old_remote_format = Some(remote);
|
old_remote_format = Some(remote);
|
||||||
|
|
||||||
@ -182,7 +182,7 @@ impl TryFrom<&PathBuf> for Manifest {
|
|||||||
if !new_remote_format_exists {
|
if !new_remote_format_exists {
|
||||||
// Fetch the author from the old remote.
|
// Fetch the author from the old remote.
|
||||||
let remote_author = old_remote
|
let remote_author = old_remote
|
||||||
.split("/") // Split the old remote as '"{author}' and '{package_name}"'
|
.split('/') // Split the old remote as '"{author}' and '{package_name}"'
|
||||||
.collect::<Vec<&str>>()[0] // Fetch just the '"{author}'
|
.collect::<Vec<&str>>()[0] // Fetch just the '"{author}'
|
||||||
.replace(&['\"', ' '][..], ""); // Remove the quotes from the author string
|
.replace(&['\"', ' '][..], ""); // Remove the quotes from the author string
|
||||||
|
|
||||||
|
@ -102,17 +102,17 @@ impl ZipFile {
|
|||||||
// Write file or directory
|
// Write file or directory
|
||||||
if path.is_file() {
|
if path.is_file() {
|
||||||
tracing::info!("Adding file {:?} as {:?}", path, name);
|
tracing::info!("Adding file {:?} as {:?}", path, name);
|
||||||
zip.start_file_from_path(name, options)?;
|
zip.start_file(name.to_string_lossy(), options)?;
|
||||||
let mut f = File::open(path)?;
|
let mut f = File::open(path)?;
|
||||||
|
|
||||||
f.read_to_end(&mut buffer)?;
|
f.read_to_end(&mut buffer)?;
|
||||||
zip.write_all(&*buffer)?;
|
zip.write_all(&*buffer)?;
|
||||||
buffer.clear();
|
buffer.clear();
|
||||||
} else if name.as_os_str().len() != 0 {
|
} else if !name.as_os_str().is_empty() {
|
||||||
// Only if not root Avoids path spec / warning
|
// Only if not root Avoids path spec / warning
|
||||||
// and mapname conversion failed error on unzip
|
// and mapname conversion failed error on unzip
|
||||||
tracing::info!("Adding directory {:?} as {:?}", path, name);
|
tracing::info!("Adding directory {:?} as {:?}", path, name);
|
||||||
zip.add_directory_from_path(name, options)?;
|
zip.add_directory(name.to_string_lossy(), options)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,23 +150,23 @@ impl ZipFile {
|
|||||||
/// Check if the file path should be included in the package zip file.
|
/// Check if the file path should be included in the package zip file.
|
||||||
fn is_included(path: &Path) -> bool {
|
fn is_included(path: &Path) -> bool {
|
||||||
// excluded directories: `input`, `output`, `imports`
|
// excluded directories: `input`, `output`, `imports`
|
||||||
if path.ends_with(INPUTS_DIRECTORY_NAME.trim_end_matches("/"))
|
if path.ends_with(INPUTS_DIRECTORY_NAME.trim_end_matches('/'))
|
||||||
| path.ends_with(OUTPUTS_DIRECTORY_NAME.trim_end_matches("/"))
|
| path.ends_with(OUTPUTS_DIRECTORY_NAME.trim_end_matches('/'))
|
||||||
| path.ends_with(IMPORTS_DIRECTORY_NAME.trim_end_matches("/"))
|
| path.ends_with(IMPORTS_DIRECTORY_NAME.trim_end_matches('/'))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// excluded extensions: `.in`, `.bytes`, `lpk`, `lvk`, `.proof`, `.sum`, `.zip`, `.bytes`
|
// excluded extensions: `.in`, `.bytes`, `lpk`, `lvk`, `.proof`, `.sum`, `.zip`, `.bytes`
|
||||||
if let Some(true) = path.extension().map(|ext| {
|
if let Some(true) = path.extension().map(|ext| {
|
||||||
ext.eq(INPUT_FILE_EXTENSION.trim_start_matches("."))
|
ext.eq(INPUT_FILE_EXTENSION.trim_start_matches('.'))
|
||||||
| ext.eq(ZIP_FILE_EXTENSION.trim_start_matches("."))
|
| ext.eq(ZIP_FILE_EXTENSION.trim_start_matches('.'))
|
||||||
| ext.eq(PROVING_KEY_FILE_EXTENSION.trim_start_matches("."))
|
| ext.eq(PROVING_KEY_FILE_EXTENSION.trim_start_matches('.'))
|
||||||
| ext.eq(VERIFICATION_KEY_FILE_EXTENSION.trim_start_matches("."))
|
| ext.eq(VERIFICATION_KEY_FILE_EXTENSION.trim_start_matches('.'))
|
||||||
| ext.eq(PROOF_FILE_EXTENSION.trim_start_matches("."))
|
| ext.eq(PROOF_FILE_EXTENSION.trim_start_matches('.'))
|
||||||
| ext.eq(CHECKSUM_FILE_EXTENSION.trim_start_matches("."))
|
| ext.eq(CHECKSUM_FILE_EXTENSION.trim_start_matches('.'))
|
||||||
| ext.eq(ZIP_FILE_EXTENSION.trim_start_matches("."))
|
| ext.eq(ZIP_FILE_EXTENSION.trim_start_matches('.'))
|
||||||
| ext.eq(CIRCUIT_FILE_EXTENSION.trim_start_matches("."))
|
| ext.eq(CIRCUIT_FILE_EXTENSION.trim_start_matches('.'))
|
||||||
}) {
|
}) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -177,12 +177,12 @@ fn is_included(path: &Path) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Only allow additional files in the `src/` directory
|
// Only allow additional files in the `src/` directory
|
||||||
if !path.starts_with(SOURCE_DIRECTORY_NAME.trim_end_matches("/")) {
|
if !path.starts_with(SOURCE_DIRECTORY_NAME.trim_end_matches('/')) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow the `.leo` files in the `src/` directory
|
// Allow the `.leo` files in the `src/` directory
|
||||||
path.extension()
|
path.extension()
|
||||||
.map(|ext| ext.eq(SOURCE_FILE_EXTENSION.trim_start_matches(".")))
|
.map(|ext| ext.eq(SOURCE_FILE_EXTENSION.trim_start_matches('.')))
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user