From 27458e93aad5e4130e346064bed7806e6d77ecf0 Mon Sep 17 00:00:00 2001 From: TomAFrench Date: Wed, 5 Jun 2024 10:55:04 +0000 Subject: [PATCH 1/3] chore: make `nargo` and debug info generic --- compiler/noirc_printable_type/src/lib.rs | 58 ++++++++++---------- tooling/acvm_cli/src/errors.rs | 3 +- tooling/debugger/src/context.rs | 6 +-- tooling/debugger/src/foreign_calls.rs | 16 +++--- tooling/debugger/src/lib.rs | 2 +- tooling/debugger/src/repl.rs | 2 +- tooling/nargo/src/artifacts/debug_vars.rs | 30 +++++------ tooling/nargo/src/errors.rs | 24 ++++----- tooling/nargo/src/ops/execute.rs | 53 +++++++++---------- tooling/nargo/src/ops/foreign_calls.rs | 64 +++++++++++------------ tooling/nargo/src/ops/test.rs | 2 +- tooling/nargo_cli/src/errors.rs | 4 +- tooling/noirc_abi/src/lib.rs | 6 +-- 13 files changed, 133 insertions(+), 137 deletions(-) diff --git a/compiler/noirc_printable_type/src/lib.rs b/compiler/noirc_printable_type/src/lib.rs index a12ecf01b56..7659b56ae23 100644 --- a/compiler/noirc_printable_type/src/lib.rs +++ b/compiler/noirc_printable_type/src/lib.rs @@ -1,6 +1,6 @@ use std::{collections::BTreeMap, str}; -use acvm::{acir::AcirField, brillig_vm::brillig::ForeignCallParam, FieldElement}; +use acvm::{acir::AcirField, brillig_vm::brillig::ForeignCallParam}; use iter_extended::vecmap; use regex::{Captures, Regex}; use serde::{Deserialize, Serialize}; @@ -51,19 +51,19 @@ pub enum PrintableType { /// For example, a toml file will parse into TomlTypes /// and those TomlTypes will be mapped to Value #[derive(Debug, Clone, Serialize, PartialEq)] -pub enum PrintableValue { - Field(FieldElement), +pub enum PrintableValue { + Field(F), String(String), - Vec { array_elements: Vec, is_slice: bool }, - Struct(BTreeMap), + Vec { array_elements: Vec>, is_slice: bool }, + Struct(BTreeMap>), Other, } /// In order to display a `PrintableValue` we need a `PrintableType` to accurately /// convert the value into a human-readable format. -pub enum PrintableValueDisplay { - Plain(PrintableValue, PrintableType), - FmtString(String, Vec<(PrintableValue, PrintableType)>), +pub enum PrintableValueDisplay { + Plain(PrintableValue, PrintableType), + FmtString(String, Vec<(PrintableValue, PrintableType)>), } #[derive(Debug, Error)] @@ -81,12 +81,10 @@ pub enum ForeignCallError { ResolvedAssertMessage(String), } -impl TryFrom<&[ForeignCallParam]> for PrintableValueDisplay { +impl TryFrom<&[ForeignCallParam]> for PrintableValueDisplay { type Error = ForeignCallError; - fn try_from( - foreign_call_inputs: &[ForeignCallParam], - ) -> Result { + fn try_from(foreign_call_inputs: &[ForeignCallParam]) -> Result { let (is_fmt_str, foreign_call_inputs) = foreign_call_inputs.split_last().ok_or(ForeignCallError::MissingForeignCallInputs)?; @@ -98,9 +96,9 @@ impl TryFrom<&[ForeignCallParam]> for PrintableValueDisplay { } } -fn convert_string_inputs( - foreign_call_inputs: &[ForeignCallParam], -) -> Result { +fn convert_string_inputs( + foreign_call_inputs: &[ForeignCallParam], +) -> Result, ForeignCallError> { // Fetch the PrintableType from the foreign call input // The remaining input values should hold what is to be printed let (printable_type_as_values, input_values) = @@ -115,9 +113,9 @@ fn convert_string_inputs( Ok(PrintableValueDisplay::Plain(value, printable_type)) } -fn convert_fmt_string_inputs( - foreign_call_inputs: &[ForeignCallParam], -) -> Result { +fn convert_fmt_string_inputs( + foreign_call_inputs: &[ForeignCallParam], +) -> Result, ForeignCallError> { let (message, input_and_printable_types) = foreign_call_inputs.split_first().ok_or(ForeignCallError::MissingForeignCallInputs)?; @@ -144,8 +142,8 @@ fn convert_fmt_string_inputs( Ok(PrintableValueDisplay::FmtString(message_as_string, output)) } -fn fetch_printable_type( - printable_type: &ForeignCallParam, +fn fetch_printable_type( + printable_type: &ForeignCallParam, ) -> Result { let printable_type_as_fields = printable_type.fields(); let printable_type_as_string = decode_string_value(&printable_type_as_fields); @@ -154,7 +152,7 @@ fn fetch_printable_type( Ok(printable_type) } -fn to_string(value: &PrintableValue, typ: &PrintableType) -> Option { +fn to_string(value: &PrintableValue, typ: &PrintableType) -> Option { let mut output = String::new(); match (value, typ) { (PrintableValue::Field(f), PrintableType::Field) => { @@ -269,7 +267,7 @@ fn replace_all( Ok(new) } -impl std::fmt::Display for PrintableValueDisplay { +impl std::fmt::Display for PrintableValueDisplay { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Self::Plain(value, typ) => { @@ -295,7 +293,7 @@ impl std::fmt::Display for PrintableValueDisplay { /// A singular '0' will be prepended as well if the trimmed string has an odd length. /// A hex string's length needs to be even to decode into bytes, as two digits correspond to /// one byte. -fn format_field_string(field: FieldElement) -> String { +fn format_field_string(field: F) -> String { if field.is_zero() { return "0x00".to_owned(); } @@ -306,11 +304,11 @@ fn format_field_string(field: FieldElement) -> String { "0x".to_owned() + &trimmed_field } -/// Assumes that `field_iterator` contains enough [FieldElement] in order to decode the [PrintableType] -pub fn decode_value( - field_iterator: &mut impl Iterator, +/// Assumes that `field_iterator` contains enough field elements in order to decode the [PrintableType] +pub fn decode_value( + field_iterator: &mut impl Iterator, typ: &PrintableType, -) -> PrintableValue { +) -> PrintableValue { match typ { PrintableType::Field | PrintableType::SignedInteger { .. } @@ -346,7 +344,7 @@ pub fn decode_value( is_slice: false, }, PrintableType::String { length } => { - let field_elements: Vec = field_iterator.take(*length as usize).collect(); + let field_elements: Vec = field_iterator.take(*length as usize).collect(); PrintableValue::String(decode_string_value(&field_elements)) } @@ -372,11 +370,11 @@ pub fn decode_value( // we decode the reference, but it's not really used for printing decode_value(field_iterator, typ) } - PrintableType::Unit => PrintableValue::Field(FieldElement::zero()), + PrintableType::Unit => PrintableValue::Field(F::zero()), } } -pub fn decode_string_value(field_elements: &[FieldElement]) -> String { +pub fn decode_string_value(field_elements: &[F]) -> String { // TODO: Replace with `into` when Char is supported let string_as_slice = vecmap(field_elements, |e| { let mut field_as_bytes = e.to_be_bytes(); diff --git a/tooling/acvm_cli/src/errors.rs b/tooling/acvm_cli/src/errors.rs index 8bc79347159..886c1bf80f2 100644 --- a/tooling/acvm_cli/src/errors.rs +++ b/tooling/acvm_cli/src/errors.rs @@ -1,3 +1,4 @@ +use acir::FieldElement; use nargo::NargoError; use std::path::PathBuf; use thiserror::Error; @@ -34,7 +35,7 @@ pub(crate) enum CliError { /// Error related to circuit execution #[error(transparent)] - CircuitExecutionError(#[from] NargoError), + CircuitExecutionError(#[from] NargoError), /// Input Witness Value Error #[error("Error: failed to parse witness value {0}")] diff --git a/tooling/debugger/src/context.rs b/tooling/debugger/src/context.rs index 9dc5c758c6f..5d0916b4863 100644 --- a/tooling/debugger/src/context.rs +++ b/tooling/debugger/src/context.rs @@ -23,7 +23,7 @@ pub(super) enum DebugCommandResult { Done, Ok, BreakpointReached(OpcodeLocation), - Error(NargoError), + Error(NargoError), } pub(super) struct DebugContext<'a, B: BlackBoxFunctionSolver> { @@ -482,11 +482,11 @@ impl<'a, B: BlackBoxFunctionSolver> DebugContext<'a, B> { } } - pub(super) fn get_variables(&self) -> Vec { + pub(super) fn get_variables(&self) -> Vec> { return self.foreign_call_executor.get_variables(); } - pub(super) fn current_stack_frame(&self) -> Option { + pub(super) fn current_stack_frame(&self) -> Option> { return self.foreign_call_executor.current_stack_frame(); } diff --git a/tooling/debugger/src/foreign_calls.rs b/tooling/debugger/src/foreign_calls.rs index 6989936ae93..03b1a35dfa5 100644 --- a/tooling/debugger/src/foreign_calls.rs +++ b/tooling/debugger/src/foreign_calls.rs @@ -38,14 +38,14 @@ impl DebugForeignCall { } } -pub trait DebugForeignCallExecutor: ForeignCallExecutor { - fn get_variables(&self) -> Vec; - fn current_stack_frame(&self) -> Option; +pub trait DebugForeignCallExecutor: ForeignCallExecutor { + fn get_variables(&self) -> Vec>; + fn current_stack_frame(&self) -> Option>; } pub struct DefaultDebugForeignCallExecutor { - executor: DefaultForeignCallExecutor, - pub debug_vars: DebugVars, + executor: DefaultForeignCallExecutor, + pub debug_vars: DebugVars, } impl DefaultDebugForeignCallExecutor { @@ -73,11 +73,11 @@ impl DefaultDebugForeignCallExecutor { } impl DebugForeignCallExecutor for DefaultDebugForeignCallExecutor { - fn get_variables(&self) -> Vec { + fn get_variables(&self) -> Vec> { self.debug_vars.get_variables() } - fn current_stack_frame(&self) -> Option { + fn current_stack_frame(&self) -> Option> { self.debug_vars.current_stack_frame() } } @@ -90,7 +90,7 @@ fn debug_fn_id(value: &FieldElement) -> DebugFnId { DebugFnId(value.to_u128() as u32) } -impl ForeignCallExecutor for DefaultDebugForeignCallExecutor { +impl ForeignCallExecutor for DefaultDebugForeignCallExecutor { fn execute( &mut self, foreign_call: &ForeignCallWaitInfo, diff --git a/tooling/debugger/src/lib.rs b/tooling/debugger/src/lib.rs index d7a1337c82f..9168a6228f0 100644 --- a/tooling/debugger/src/lib.rs +++ b/tooling/debugger/src/lib.rs @@ -24,7 +24,7 @@ pub fn debug_circuit>( debug_artifact: DebugArtifact, initial_witness: WitnessMap, unconstrained_functions: &[BrilligBytecode], -) -> Result>, NargoError> { +) -> Result>, NargoError> { repl::run(blackbox_solver, circuit, &debug_artifact, initial_witness, unconstrained_functions) } diff --git a/tooling/debugger/src/repl.rs b/tooling/debugger/src/repl.rs index 5aef12ad8d4..07f9333d51c 100644 --- a/tooling/debugger/src/repl.rs +++ b/tooling/debugger/src/repl.rs @@ -382,7 +382,7 @@ pub fn run>( debug_artifact: &DebugArtifact, initial_witness: WitnessMap, unconstrained_functions: &[BrilligBytecode], -) -> Result>, NargoError> { +) -> Result>, NargoError> { let context = RefCell::new(ReplDebugger::new( blackbox_solver, circuit, diff --git a/tooling/nargo/src/artifacts/debug_vars.rs b/tooling/nargo/src/artifacts/debug_vars.rs index 3695fa47842..56c0f70f979 100644 --- a/tooling/nargo/src/artifacts/debug_vars.rs +++ b/tooling/nargo/src/artifacts/debug_vars.rs @@ -1,4 +1,4 @@ -use acvm::FieldElement; +use acvm::AcirField; use noirc_errors::debug_info::{ DebugFnId, DebugFunction, DebugInfo, DebugTypeId, DebugVarId, DebugVariable, }; @@ -6,31 +6,31 @@ use noirc_printable_type::{decode_value, PrintableType, PrintableValue}; use std::collections::HashMap; #[derive(Debug, Default, Clone)] -pub struct DebugVars { +pub struct DebugVars { variables: HashMap, functions: HashMap, types: HashMap, - frames: Vec<(DebugFnId, HashMap)>, + frames: Vec<(DebugFnId, HashMap>)>, } -pub struct StackFrame<'a> { +pub struct StackFrame<'a, F> { pub function_name: &'a str, pub function_params: Vec<&'a str>, - pub variables: Vec<(&'a str, &'a PrintableValue, &'a PrintableType)>, + pub variables: Vec<(&'a str, &'a PrintableValue, &'a PrintableType)>, } -impl DebugVars { +impl DebugVars { pub fn insert_debug_info(&mut self, info: &DebugInfo) { self.variables.extend(info.variables.clone()); self.types.extend(info.types.clone()); self.functions.extend(info.functions.clone()); } - pub fn get_variables(&self) -> Vec { + pub fn get_variables(&self) -> Vec> { self.frames.iter().map(|(fn_id, frame)| self.build_stack_frame(fn_id, frame)).collect() } - pub fn current_stack_frame(&self) -> Option { + pub fn current_stack_frame(&self) -> Option> { self.frames.last().map(|(fn_id, frame)| self.build_stack_frame(fn_id, frame)) } @@ -44,13 +44,13 @@ impl DebugVars { fn build_stack_frame<'a>( &'a self, fn_id: &DebugFnId, - frame: &'a HashMap, - ) -> StackFrame { + frame: &'a HashMap>, + ) -> StackFrame { let debug_fn = &self.functions.get(fn_id).expect("failed to find function metadata"); let params: Vec<&str> = debug_fn.arg_names.iter().map(|arg_name| arg_name.as_str()).collect(); - let vars: Vec<(&str, &PrintableValue, &PrintableType)> = frame + let vars: Vec<(&str, &PrintableValue, &PrintableType)> = frame .iter() .filter_map(|(var_id, var_value)| { self.lookup_var(*var_id).map(|(name, typ)| (name, var_value, typ)) @@ -64,7 +64,7 @@ impl DebugVars { } } - pub fn assign_var(&mut self, var_id: DebugVarId, values: &[FieldElement]) { + pub fn assign_var(&mut self, var_id: DebugVarId, values: &[F]) { let type_id = &self.variables.get(&var_id).unwrap().debug_type_id; let ptype = self.types.get(type_id).unwrap(); @@ -75,9 +75,9 @@ impl DebugVars { .insert(var_id, decode_value(&mut values.iter().copied(), ptype)); } - pub fn assign_field(&mut self, var_id: DebugVarId, indexes: Vec, values: &[FieldElement]) { + pub fn assign_field(&mut self, var_id: DebugVarId, indexes: Vec, values: &[F]) { let current_frame = &mut self.frames.last_mut().expect("unexpected empty stack frames").1; - let mut cursor: &mut PrintableValue = current_frame + let mut cursor: &mut PrintableValue = current_frame .get_mut(&var_id) .unwrap_or_else(|| panic!("value unavailable for var_id {var_id:?}")); let cursor_type_id = &self @@ -146,7 +146,7 @@ impl DebugVars { *cursor = decode_value(&mut values.iter().copied(), cursor_type); } - pub fn assign_deref(&mut self, _var_id: DebugVarId, _values: &[FieldElement]) { + pub fn assign_deref(&mut self, _var_id: DebugVarId, _values: &[F]) { unimplemented![] } diff --git a/tooling/nargo/src/errors.rs b/tooling/nargo/src/errors.rs index 200420e5ce5..9c8974b0c22 100644 --- a/tooling/nargo/src/errors.rs +++ b/tooling/nargo/src/errors.rs @@ -4,9 +4,7 @@ use acvm::{ acir::circuit::{ ErrorSelector, OpcodeLocation, RawAssertionPayload, ResolvedAssertionPayload, ResolvedOpcodeLocation, - }, - pwg::{ErrorLocation, OpcodeResolutionError}, - FieldElement, + }, pwg::{ErrorLocation, OpcodeResolutionError}, AcirField, FieldElement }; use noirc_abi::{display_abi_error, Abi, AbiErrorType}; use noirc_errors::{ @@ -40,21 +38,21 @@ impl From for CompileError { } #[derive(Debug, Error)] -pub enum NargoError { +pub enum NargoError { /// Error while compiling Noir into ACIR. #[error("Failed to compile circuit")] CompilationError, /// ACIR circuit execution error #[error(transparent)] - ExecutionError(#[from] ExecutionError), + ExecutionError(#[from] ExecutionError), /// Oracle handling error #[error(transparent)] ForeignCallError(#[from] ForeignCallError), } -impl NargoError { +impl NargoError { /// Extracts the user defined failure message from the ExecutionError /// If one exists. /// @@ -94,17 +92,17 @@ impl NargoError { } #[derive(Debug, Error)] -pub enum ExecutionError { +pub enum ExecutionError { #[error("Failed assertion")] - AssertionFailed(ResolvedAssertionPayload, Vec), + AssertionFailed(ResolvedAssertionPayload, Vec), #[error("Failed to solve program: '{}'", .0)] - SolvingError(OpcodeResolutionError, Option>), + SolvingError(OpcodeResolutionError, Option>), } /// Extracts the opcode locations from a nargo error. -fn extract_locations_from_error( - error: &ExecutionError, +fn extract_locations_from_error( + error: &ExecutionError, debug: &[DebugInfo], ) -> Option> { let mut opcode_locations = match error { @@ -163,7 +161,7 @@ fn extract_locations_from_error( fn extract_message_from_error( error_types: &BTreeMap, - nargo_err: &NargoError, + nargo_err: &NargoError, ) -> String { match nargo_err { NargoError::ExecutionError(ExecutionError::AssertionFailed( @@ -198,7 +196,7 @@ fn extract_message_from_error( /// Tries to generate a runtime diagnostic from a nargo error. It will successfully do so if it's a runtime error with a call stack. pub fn try_to_diagnose_runtime_error( - nargo_err: &NargoError, + nargo_err: &NargoError, abi: &Abi, debug: &[DebugInfo], ) -> Option { diff --git a/tooling/nargo/src/ops/execute.rs b/tooling/nargo/src/ops/execute.rs index 42e93e0e3cf..c9cc60d03d9 100644 --- a/tooling/nargo/src/ops/execute.rs +++ b/tooling/nargo/src/ops/execute.rs @@ -5,24 +5,24 @@ use acvm::acir::circuit::{ use acvm::acir::native_types::WitnessStack; use acvm::pwg::{ACVMStatus, ErrorLocation, OpcodeNotSolvable, OpcodeResolutionError, ACVM}; use acvm::{acir::circuit::Circuit, acir::native_types::WitnessMap}; -use acvm::{BlackBoxFunctionSolver, FieldElement}; +use acvm::{AcirField, BlackBoxFunctionSolver}; use crate::errors::ExecutionError; use crate::NargoError; use super::foreign_calls::ForeignCallExecutor; -struct ProgramExecutor<'a, B: BlackBoxFunctionSolver, F: ForeignCallExecutor> { - functions: &'a [Circuit], +struct ProgramExecutor<'a, F, B: BlackBoxFunctionSolver, E: ForeignCallExecutor> { + functions: &'a [Circuit], - unconstrained_functions: &'a [BrilligBytecode], + unconstrained_functions: &'a [BrilligBytecode], // This gets built as we run through the program looking at each function call - witness_stack: WitnessStack, + witness_stack: WitnessStack, blackbox_solver: &'a B, - foreign_call_executor: &'a mut F, + foreign_call_executor: &'a mut E, // The Noir compiler codegens per function and call stacks are not shared across ACIR function calls. // We must rebuild a call stack when executing a program of many circuits. @@ -34,14 +34,14 @@ struct ProgramExecutor<'a, B: BlackBoxFunctionSolver, F: ForeignCa current_function_index: usize, } -impl<'a, B: BlackBoxFunctionSolver, F: ForeignCallExecutor> - ProgramExecutor<'a, B, F> +impl<'a, F: AcirField, B: BlackBoxFunctionSolver, E: ForeignCallExecutor> + ProgramExecutor<'a, F, B, E> { fn new( - functions: &'a [Circuit], - unconstrained_functions: &'a [BrilligBytecode], + functions: &'a [Circuit], + unconstrained_functions: &'a [BrilligBytecode], blackbox_solver: &'a B, - foreign_call_executor: &'a mut F, + foreign_call_executor: &'a mut E, ) -> Self { ProgramExecutor { functions, @@ -54,15 +54,15 @@ impl<'a, B: BlackBoxFunctionSolver, F: ForeignCallExecutor> } } - fn finalize(self) -> WitnessStack { + fn finalize(self) -> WitnessStack { self.witness_stack } #[tracing::instrument(level = "trace", skip_all)] fn execute_circuit( &mut self, - initial_witness: WitnessMap, - ) -> Result, NargoError> { + initial_witness: WitnessMap, + ) -> Result, NargoError> { let circuit = &self.functions[self.current_function_index]; let mut acvm = ACVM::new( self.blackbox_solver, @@ -109,14 +109,13 @@ impl<'a, B: BlackBoxFunctionSolver, F: ForeignCallExecutor> _ => None, }; - let assertion_payload: Option> = - match &error { - OpcodeResolutionError::BrilligFunctionFailed { payload, .. } - | OpcodeResolutionError::UnsatisfiedConstrain { payload, .. } => { - payload.clone() - } - _ => None, - }; + let assertion_payload: Option> = match &error { + OpcodeResolutionError::BrilligFunctionFailed { payload, .. } + | OpcodeResolutionError::UnsatisfiedConstrain { payload, .. } => { + payload.clone() + } + _ => None, + }; return Err(NargoError::ExecutionError(match assertion_payload { Some(payload) => ExecutionError::AssertionFailed( @@ -174,12 +173,12 @@ impl<'a, B: BlackBoxFunctionSolver, F: ForeignCallExecutor> } #[tracing::instrument(level = "trace", skip_all)] -pub fn execute_program, F: ForeignCallExecutor>( - program: &Program, - initial_witness: WitnessMap, +pub fn execute_program, E: ForeignCallExecutor>( + program: &Program, + initial_witness: WitnessMap, blackbox_solver: &B, - foreign_call_executor: &mut F, -) -> Result, NargoError> { + foreign_call_executor: &mut E, +) -> Result, NargoError> { let mut executor = ProgramExecutor::new( &program.functions, &program.unconstrained_functions, diff --git a/tooling/nargo/src/ops/foreign_calls.rs b/tooling/nargo/src/ops/foreign_calls.rs index c6b284beb13..c1e55ddcb47 100644 --- a/tooling/nargo/src/ops/foreign_calls.rs +++ b/tooling/nargo/src/ops/foreign_calls.rs @@ -1,16 +1,17 @@ use acvm::{ acir::brillig::{ForeignCallParam, ForeignCallResult}, pwg::ForeignCallWaitInfo, - AcirField, FieldElement, + AcirField, }; use jsonrpc::{arg as build_json_rpc_arg, minreq_http::Builder, Client}; use noirc_printable_type::{decode_string_value, ForeignCallError, PrintableValueDisplay}; +use serde::{Deserialize, Serialize}; -pub trait ForeignCallExecutor { +pub trait ForeignCallExecutor { fn execute( &mut self, - foreign_call: &ForeignCallWaitInfo, - ) -> Result, ForeignCallError>; + foreign_call: &ForeignCallWaitInfo, + ) -> Result, ForeignCallError>; } /// This enumeration represents the Brillig foreign calls that are natively supported by nargo. @@ -60,22 +61,22 @@ impl ForeignCall { /// This struct represents an oracle mock. It can be used for testing programs that use oracles. #[derive(Debug, PartialEq, Eq, Clone)] -struct MockedCall { +struct MockedCall { /// The id of the mock, used to update or remove it id: usize, /// The oracle it's mocking name: String, /// Optionally match the parameters - params: Option>>, + params: Option>>, /// The parameters with which the mock was last called - last_called_params: Option>>, + last_called_params: Option>>, /// The result to return when this mock is called - result: ForeignCallResult, + result: ForeignCallResult, /// How many times should this mock be called before it is removed times_left: Option, } -impl MockedCall { +impl MockedCall { fn new(id: usize, name: String) -> Self { Self { id, @@ -88,25 +89,25 @@ impl MockedCall { } } -impl MockedCall { - fn matches(&self, name: &str, params: &[ForeignCallParam]) -> bool { +impl MockedCall { + fn matches(&self, name: &str, params: &[ForeignCallParam]) -> bool { self.name == name && (self.params.is_none() || self.params.as_deref() == Some(params)) } } #[derive(Debug, Default)] -pub struct DefaultForeignCallExecutor { +pub struct DefaultForeignCallExecutor { /// Mocks have unique ids used to identify them in Noir, allowing to update or remove them. last_mock_id: usize, /// The registered mocks - mocked_responses: Vec, + mocked_responses: Vec>, /// Whether to print [`ForeignCall::Print`] output. show_output: bool, /// JSON RPC client to resolve foreign calls external_resolver: Option, } -impl DefaultForeignCallExecutor { +impl DefaultForeignCallExecutor { pub fn new(show_output: bool, resolver_url: Option<&str>) -> Self { let oracle_resolver = resolver_url.map(|resolver_url| { let mut transport_builder = @@ -123,15 +124,16 @@ impl DefaultForeignCallExecutor { DefaultForeignCallExecutor { show_output, external_resolver: oracle_resolver, - ..DefaultForeignCallExecutor::default() + mocked_responses: Vec::new(), + last_mock_id: 0, } } } -impl DefaultForeignCallExecutor { +impl DefaultForeignCallExecutor { fn extract_mock_id( - foreign_call_inputs: &[ForeignCallParam], - ) -> Result<(usize, &[ForeignCallParam]), ForeignCallError> { + foreign_call_inputs: &[ForeignCallParam], + ) -> Result<(usize, &[ForeignCallParam]), ForeignCallError> { let (id, params) = foreign_call_inputs.split_first().ok_or(ForeignCallError::MissingForeignCallInputs)?; let id = @@ -140,22 +142,20 @@ impl DefaultForeignCallExecutor { Ok((id, params)) } - fn find_mock_by_id(&self, id: usize) -> Option<&MockedCall> { + fn find_mock_by_id(&self, id: usize) -> Option<&MockedCall> { self.mocked_responses.iter().find(|response| response.id == id) } - fn find_mock_by_id_mut(&mut self, id: usize) -> Option<&mut MockedCall> { + fn find_mock_by_id_mut(&mut self, id: usize) -> Option<&mut MockedCall> { self.mocked_responses.iter_mut().find(|response| response.id == id) } - fn parse_string(param: &ForeignCallParam) -> String { + fn parse_string(param: &ForeignCallParam) -> String { let fields: Vec<_> = param.fields().to_vec(); decode_string_value(&fields) } - fn execute_print( - foreign_call_inputs: &[ForeignCallParam], - ) -> Result<(), ForeignCallError> { + fn execute_print(foreign_call_inputs: &[ForeignCallParam]) -> Result<(), ForeignCallError> { let skip_newline = foreign_call_inputs[0].unwrap_field().is_zero(); let foreign_call_inputs = @@ -168,10 +168,10 @@ impl DefaultForeignCallExecutor { } fn format_printable_value( - foreign_call_inputs: &[ForeignCallParam], + foreign_call_inputs: &[ForeignCallParam], skip_newline: bool, ) -> Result { - let display_values: PrintableValueDisplay = foreign_call_inputs.try_into()?; + let display_values: PrintableValueDisplay = foreign_call_inputs.try_into()?; let result = format!("{display_values}{}", if skip_newline { "" } else { "\n" }); @@ -179,11 +179,11 @@ impl DefaultForeignCallExecutor { } } -impl ForeignCallExecutor for DefaultForeignCallExecutor { +impl Deserialize<'a>> ForeignCallExecutor for DefaultForeignCallExecutor { fn execute( &mut self, - foreign_call: &ForeignCallWaitInfo, - ) -> Result, ForeignCallError> { + foreign_call: &ForeignCallWaitInfo, + ) -> Result, ForeignCallError> { let foreign_call_name = foreign_call.function.as_str(); match ForeignCall::lookup(foreign_call_name) { Some(ForeignCall::Print) => { @@ -199,7 +199,7 @@ impl ForeignCallExecutor for DefaultForeignCallExecutor { self.mocked_responses.push(MockedCall::new(id, mock_oracle_name)); self.last_mock_id += 1; - Ok(FieldElement::from(id).into()) + Ok(F::from(id).into()) } Some(ForeignCall::SetMockParams) => { let (id, params) = Self::extract_mock_id(&foreign_call.inputs)?; @@ -282,7 +282,7 @@ impl ForeignCallExecutor for DefaultForeignCallExecutor { let response = external_resolver.send_request(req)?; - let parsed_response: ForeignCallResult = response.result()?; + let parsed_response: ForeignCallResult = response.result()?; Ok(parsed_response) } else { @@ -369,7 +369,7 @@ mod tests { fn test_oracle_resolver_echo() { let (server, url) = build_oracle_server(); - let mut executor = DefaultForeignCallExecutor::new(false, Some(&url)); + let mut executor = DefaultForeignCallExecutor::::new(false, Some(&url)); let foreign_call = ForeignCallWaitInfo { function: "echo".to_string(), diff --git a/tooling/nargo/src/ops/test.rs b/tooling/nargo/src/ops/test.rs index ed45251ac8a..ace2e9f0d0c 100644 --- a/tooling/nargo/src/ops/test.rs +++ b/tooling/nargo/src/ops/test.rs @@ -76,7 +76,7 @@ fn test_status_program_compile_pass( test_function: &TestFunction, abi: Abi, debug: Vec, - circuit_execution: Result, NargoError>, + circuit_execution: Result, NargoError>, ) -> TestStatus { let circuit_execution_err = match circuit_execution { // Circuit execution was successful; ie no errors or unsatisfied constraints diff --git a/tooling/nargo_cli/src/errors.rs b/tooling/nargo_cli/src/errors.rs index 3e0b13a9cbc..b28012ae7aa 100644 --- a/tooling/nargo_cli/src/errors.rs +++ b/tooling/nargo_cli/src/errors.rs @@ -1,4 +1,4 @@ -use acvm::acir::native_types::WitnessStackError; +use acvm::{acir::native_types::WitnessStackError, FieldElement}; use nargo::{errors::CompileError, NargoError}; use nargo_toml::ManifestError; use noir_debugger::errors::DapError; @@ -54,7 +54,7 @@ pub(crate) enum CliError { /// Error from Nargo #[error(transparent)] - NargoError(#[from] NargoError), + NargoError(#[from] NargoError), /// Error from Manifest #[error(transparent)] diff --git a/tooling/noirc_abi/src/lib.rs b/tooling/noirc_abi/src/lib.rs index 0acace71fb3..57913e00b52 100644 --- a/tooling/noirc_abi/src/lib.rs +++ b/tooling/noirc_abi/src/lib.rs @@ -620,10 +620,10 @@ impl AbiErrorType { } } -pub fn display_abi_error( - fields: &[FieldElement], +pub fn display_abi_error( + fields: &[F], error_type: AbiErrorType, -) -> PrintableValueDisplay { +) -> PrintableValueDisplay { match error_type { AbiErrorType::FmtString { length, item_types } => { let mut fields_iter = fields.iter().copied(); From ecd508a7a7122b6e1f95555eb957040cd327465e Mon Sep 17 00:00:00 2001 From: TomAFrench Date: Thu, 6 Jun 2024 14:11:55 +0000 Subject: [PATCH 2/3] chore: fmt --- tooling/nargo/src/errors.rs | 4 +++- tooling/nargo/src/ops/foreign_calls.rs | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/tooling/nargo/src/errors.rs b/tooling/nargo/src/errors.rs index 9c8974b0c22..b2248605cb5 100644 --- a/tooling/nargo/src/errors.rs +++ b/tooling/nargo/src/errors.rs @@ -4,7 +4,9 @@ use acvm::{ acir::circuit::{ ErrorSelector, OpcodeLocation, RawAssertionPayload, ResolvedAssertionPayload, ResolvedOpcodeLocation, - }, pwg::{ErrorLocation, OpcodeResolutionError}, AcirField, FieldElement + }, + pwg::{ErrorLocation, OpcodeResolutionError}, + AcirField, FieldElement, }; use noirc_abi::{display_abi_error, Abi, AbiErrorType}; use noirc_errors::{ diff --git a/tooling/nargo/src/ops/foreign_calls.rs b/tooling/nargo/src/ops/foreign_calls.rs index c1e55ddcb47..baa6ffe3285 100644 --- a/tooling/nargo/src/ops/foreign_calls.rs +++ b/tooling/nargo/src/ops/foreign_calls.rs @@ -179,7 +179,9 @@ impl DefaultForeignCallExecutor { } } -impl Deserialize<'a>> ForeignCallExecutor for DefaultForeignCallExecutor { +impl Deserialize<'a>> ForeignCallExecutor + for DefaultForeignCallExecutor +{ fn execute( &mut self, foreign_call: &ForeignCallWaitInfo, From e66ad448695345ae2beac6be33b198d830cee734 Mon Sep 17 00:00:00 2001 From: Tom French Date: Mon, 10 Jun 2024 14:26:22 +0100 Subject: [PATCH 3/3] chore: clippy --- tooling/nargo/src/ops/foreign_calls.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tooling/nargo/src/ops/foreign_calls.rs b/tooling/nargo/src/ops/foreign_calls.rs index 6a58dab9858..987c7dd9cb9 100644 --- a/tooling/nargo/src/ops/foreign_calls.rs +++ b/tooling/nargo/src/ops/foreign_calls.rs @@ -114,7 +114,6 @@ pub struct DefaultForeignCallExecutor { external_resolver: Option, } - #[derive(Debug, Serialize, Deserialize)] struct ResolveForeignCallRequest { /// A session ID which allows the external RPC server to link this foreign call request to other foreign calls @@ -437,7 +436,7 @@ mod tests { fn foreign_call_executor_id_is_persistent() { let (server, url) = build_oracle_server(); - let mut executor = DefaultForeignCallExecutor::new(false, Some(&url)); + let mut executor = DefaultForeignCallExecutor::::new(false, Some(&url)); let foreign_call = ForeignCallWaitInfo { function: "id".to_string(), inputs: Vec::new() }; @@ -452,8 +451,8 @@ mod tests { fn oracle_resolver_rpc_can_distinguish_executors() { let (server, url) = build_oracle_server(); - let mut executor_1 = DefaultForeignCallExecutor::new(false, Some(&url)); - let mut executor_2 = DefaultForeignCallExecutor::new(false, Some(&url)); + let mut executor_1 = DefaultForeignCallExecutor::::new(false, Some(&url)); + let mut executor_2 = DefaultForeignCallExecutor::::new(false, Some(&url)); let foreign_call = ForeignCallWaitInfo { function: "id".to_string(), inputs: Vec::new() };