updates after @collinc97 comments

This commit is contained in:
damirka 2021-03-15 16:29:45 +03:00
parent 14d167a725
commit b58db80005
6 changed files with 118 additions and 51 deletions

View File

@ -94,13 +94,18 @@ impl Input {
Ok(())
}
/// Returns the main function input value with the given `name`, second parameter
/// is a boolean indicating whether parameter is const.
/// Returns the main function input value with the given `name`.
#[allow(clippy::ptr_arg)]
pub fn get(&self, name: &String) -> Option<(Option<InputValue>, bool)> {
pub fn get(&self, name: &String) -> Option<Option<InputValue>> {
self.program_input.get(name)
}
/// Returns the constant input value with the given `name`.
#[allow(clippy::ptr_arg)]
pub fn get_constant(&self, name: &String) -> Option<Option<InputValue>> {
self.program_input.get_constant(name)
}
/// Returns the runtime register input values
pub fn get_registers(&self) -> &Registers {
self.program_input.get_registers()

View File

@ -0,0 +1,70 @@
// Copyright (C) 2019-2021 Aleo Systems Inc.
// This file is part of the Leo library.
// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::InputValue;
use leo_input::{definitions::Definition, InputParserError};
use indexmap::IndexMap;
#[derive(Clone, PartialEq, Eq, Default)]
pub struct ConstInput {
input: IndexMap<String, Option<InputValue>>,
}
#[allow(clippy::len_without_is_empty)]
impl ConstInput {
pub fn new() -> Self {
Self::default()
}
/// Returns an empty version of this struct with `None` values.
/// Called during constraint synthesis to provide private input variables.
pub fn empty(&self) -> Self {
let mut input = self.input.clone();
input.iter_mut().for_each(|(_name, value)| {
*value = None;
});
Self { input }
}
pub fn len(&self) -> usize {
self.input.len()
}
pub fn insert(&mut self, key: String, value: Option<InputValue>) {
self.input.insert(key, value);
}
/// Parses main input definitions and stores them in `self`.
pub fn parse(&mut self, definitions: Vec<Definition>) -> Result<(), InputParserError> {
for definition in definitions {
let name = definition.parameter.variable.value;
let value = InputValue::from_expression(definition.parameter.type_, definition.expression)?;
self.insert(name, Some(value));
}
Ok(())
}
/// Returns an `Option` of the main function input at `name`. As a second
/// value in a tuple returns flag whether input is defined as a constant in input file.
pub fn get(&self, name: &str) -> Option<Option<InputValue>> {
self.input.get(name).cloned()
}
}

View File

@ -22,7 +22,6 @@ use indexmap::IndexMap;
#[derive(Clone, PartialEq, Eq, Default)]
pub struct MainInput {
input: IndexMap<String, Option<InputValue>>,
constants: IndexMap<String, Option<InputValue>>,
}
#[allow(clippy::len_without_is_empty)]
@ -35,31 +34,22 @@ impl MainInput {
/// Called during constraint synthesis to provide private input variables.
pub fn empty(&self) -> Self {
let mut input = self.input.clone();
let mut constants = self.constants.clone();
input.iter_mut().for_each(|(_name, value)| {
*value = None;
});
constants.iter_mut().for_each(|(_name, value)| {
*value = None;
});
Self { input, constants }
Self { input }
}
pub fn len(&self) -> usize {
self.input.len() + self.constants.len()
self.input.len()
}
pub fn insert(&mut self, key: String, value: Option<InputValue>) {
self.input.insert(key, value);
}
pub fn insert_constant(&mut self, key: String, value: Option<InputValue>) {
self.constants.insert(key, value);
}
/// Parses main input definitions and stores them in `self`.
pub fn parse(&mut self, definitions: Vec<Definition>) -> Result<(), InputParserError> {
for definition in definitions {
@ -72,26 +62,9 @@ impl MainInput {
Ok(())
}
/// Parses constants input definitions and stores them in `self`.
pub fn parse_constants(&mut self, definitions: Vec<Definition>) -> Result<(), InputParserError> {
for definition in definitions {
let name = definition.parameter.variable.value;
let value = InputValue::from_expression(definition.parameter.type_, definition.expression)?;
self.insert_constant(name, Some(value));
}
Ok(())
}
/// Returns an `Option` of the main function input at `name`. As a second
/// value in a tuple returns flag whether input is defined as a constant in input file.
pub fn get(&self, name: &str) -> Option<(Option<InputValue>, bool)> {
// As we check key presence in IndexMap unwraps below can be considered secure.
match (self.input.contains_key(name), self.constants.contains_key(name)) {
(true, _) => Some((self.input.get(name).cloned().unwrap(), false)),
(_, true) => Some((self.constants.get(name).cloned().unwrap(), true)),
(_, _) => None,
}
pub fn get(&self, name: &str) -> Option<Option<InputValue>> {
self.input.get(name).cloned()
}
}

View File

@ -16,6 +16,9 @@
#![allow(clippy::module_inception)]
pub mod const_input;
pub use const_input::*;
pub mod main_input;
pub use main_input::*;

View File

@ -14,7 +14,7 @@
// 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/>.
use crate::{InputValue, MainInput, Registers};
use crate::{ConstInput, InputValue, MainInput, Registers};
use leo_input::{
sections::{Header, Section},
InputParserError,
@ -23,6 +23,7 @@ use leo_input::{
#[derive(Clone, PartialEq, Eq, Default)]
pub struct ProgramInput {
pub main: MainInput,
pub constants: ConstInput,
registers: Registers,
}
@ -36,18 +37,24 @@ impl ProgramInput {
/// Called during constraint synthesis to provide private input values.
pub fn empty(&self) -> Self {
let main = self.main.empty();
let constants = self.constants.empty();
let registers = self.registers.empty();
Self { main, registers }
Self {
main,
constants,
registers,
}
}
pub fn len(&self) -> usize {
let mut len = 0;
// add main input variables
// Add main input variables and constants.
len += self.main.len();
len += self.constants.len();
// add registers
// Add registers.
if self.registers.is_present() {
len += 1;
}
@ -58,7 +65,7 @@ impl ProgramInput {
/// Parse each input included in a file and store them in `self`.
pub fn parse(&mut self, section: Section) -> Result<(), InputParserError> {
match section.header {
Header::Constants(_constants) => self.main.parse_constants(section.definitions),
Header::Constants(_constants) => self.constants.parse(section.definitions),
Header::Main(_main) => self.main.parse(section.definitions),
Header::Registers(_registers) => self.registers.parse(section.definitions),
header => Err(InputParserError::input_section_header(header)),
@ -67,10 +74,15 @@ impl ProgramInput {
/// Returns the main function input value with the given `name`
#[allow(clippy::ptr_arg)]
pub fn get(&self, name: &String) -> Option<(Option<InputValue>, bool)> {
pub fn get(&self, name: &String) -> Option<Option<InputValue>> {
self.main.get(name)
}
#[allow(clippy::ptr_arg)]
pub fn get_constant(&self, name: &String) -> Option<Option<InputValue>> {
self.constants.get(name)
}
/// Returns the runtime register input values
pub fn get_registers(&self) -> &Registers {
&self.registers

View File

@ -62,29 +62,33 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
let input_variable = input_variable.get().borrow();
let name = input_variable.name.name.clone();
let (input_option, is_const) = input.get(&name).ok_or_else(|| {
FunctionError::input_not_found(name.clone(), &function.span.clone().unwrap_or_default())
})?;
let input_value = if is_const {
self.parse_constant_main_function_input(
let input_value = match (input.get(&name), input.get_constant(&name)) {
// If input option is found in [main] section.
(Some(input_option), _) => self.parse_constant_main_function_input(
cs,
&input_variable.type_.clone(),
&name,
input_option,
&function.span.clone().unwrap_or_default(),
)?
} else {
self.allocate_main_function_input(
)?,
// If input option is found in [constants] section.
(_, Some(input_option)) => self.allocate_main_function_input(
cs,
&input_variable.type_.clone(),
&name,
input_option,
&function.span.clone().unwrap_or_default(),
)?
)?,
// When not found - Error out.
(_, _) => {
return Err(FunctionError::input_not_found(
name.clone(),
&function.span.clone().unwrap_or_default(),
));
}
};
// Store a new variable for every allocated main function input
// Store a new variable for every function input.
self.store(input_variable.id, input_value);
}
arguments.push(Cell::new(&*function.scope.alloc_expression(Expression::VariableRef(