From 0769b292cb302b68ce5cf4c18f10f88104f848a9 Mon Sep 17 00:00:00 2001 From: AztecBot Date: Sat, 26 Oct 2024 08:02:21 +0000 Subject: [PATCH] [1 changes] fix: Fix panic in comptime code (https://github.com/noir-lang/noir/pull/6361) feat: let the LSP import code action insert into existing use statements (https://github.com/noir-lang/noir/pull/6358) chore: minor tweaks to comptime doc (https://github.com/noir-lang/noir/pull/6357) feat: LSP auto-import will try to add to existing use statements (https://github.com/noir-lang/noir/pull/6354) fix: allow type aliases in let patterns (https://github.com/noir-lang/noir/pull/6356) feat(test): Run test matrix on stdlib tests (https://github.com/noir-lang/noir/pull/6352) fix(ssa): Do not mark an array from a parameter mutable (https://github.com/noir-lang/noir/pull/6355) fix: always inline `derive_generators` (https://github.com/noir-lang/noir/pull/6350) chore: add test to check that duplicate definitions generated from macros throws error (https://github.com/noir-lang/noir/pull/6351) chore: switch to btreeset for deterministic ordering (https://github.com/noir-lang/noir/pull/6348) feat(perf): Use [u32;16] for message block in sha256 (https://github.com/noir-lang/noir/pull/6324) chore: add some tests for type aliases feat: remove 'single use' intermediate variables (https://github.com/noir-lang/noir/pull/6268) feat: Sync from aztec-packages (https://github.com/noir-lang/noir/pull/6345) feat(profiler)!: New flamegraph command that profiles the opcodes executed (https://github.com/noir-lang/noir/pull/6327) feat: check trait where clause (https://github.com/noir-lang/noir/pull/6325) fix: better formatting of leading/trailing line/block comments in expression lists (https://github.com/noir-lang/noir/pull/6338) feat: let the formatter remove lambda block braces for single-statement blocks (https://github.com/noir-lang/noir/pull/6335) chore: run tests in metaprogramming.rs (https://github.com/noir-lang/noir/pull/6339) --- .noir-sync-commit | 2 +- noir/noir-repo/Cargo.lock | 37 ++ noir/noir-repo/Cargo.toml | 1 + .../opcodes/black_box_function_call.rs | 12 + .../compiler/optimizers/merge_expressions.rs | 202 +++++++ .../acvm/src/compiler/optimizers/mod.rs | 2 + .../acvm/src/compiler/transformers/mod.rs | 16 +- .../acvm-repo/acvm/src/pwg/brillig.rs | 36 +- noir/noir-repo/acvm-repo/acvm/src/pwg/mod.rs | 48 +- noir/noir-repo/acvm-repo/acvm_js/build.sh | 2 +- .../noir-repo/acvm-repo/brillig_vm/src/lib.rs | 55 +- .../compiler/integration-tests/package.json | 2 +- .../noirc_evaluator/src/brillig/brillig_ir.rs | 4 +- .../src/ssa/acir_gen/acir_ir/acir_variable.rs | 3 +- .../noirc_evaluator/src/ssa/opt/array_set.rs | 22 +- .../noirc_frontend/src/ast/statement.rs | 1 + .../noirc_frontend/src/elaborator/mod.rs | 100 +++- .../noirc_frontend/src/elaborator/scope.rs | 18 +- .../noirc_frontend/src/elaborator/traits.rs | 4 + .../src/hir/comptime/interpreter.rs | 4 +- .../noirc_frontend/src/hir_def/traits.rs | 6 + .../noirc_frontend/src/hir_def/types.rs | 5 + .../noirc_frontend/src/node_interner.rs | 1 + .../src/parser/parser/use_tree.rs | 42 +- .../compiler/noirc_frontend/src/tests.rs | 33 +- .../noirc_frontend/src/tests/aliases.rs | 33 ++ .../src/tests/metaprogramming.rs | 71 ++- .../noirc_frontend/src/tests/traits.rs | 113 ++++ .../docs/docs/noir/concepts/comptime.md | 26 +- noir/noir-repo/docs/docusaurus.config.ts | 31 - .../version-v0.36.0/how_to/_category_.json | 3 +- .../noir/concepts/data_types/_category_.json | 2 +- .../cryptographic_primitives/_category_.json | 3 +- noir/noir-repo/noir_stdlib/src/hash/mod.nr | 1 + noir/noir-repo/noir_stdlib/src/hash/sha256.nr | 429 ++++++++++++-- noir/noir-repo/scripts/bump-bb.sh | 2 +- noir/noir-repo/scripts/install_bb.sh | 2 +- .../arithmetic_generics/src/main.nr | 10 +- .../comptime_closures/src/main.nr | 2 +- .../inner_outer_cl/src/main.nr | 2 +- .../use_callers_scope/src/main.nr | 2 +- .../double_verify_honk_proof/Nargo.toml | 6 - .../double_verify_honk_proof/Prover.toml | 5 - .../double_verify_honk_proof/src/main.nr | 28 - .../Nargo.toml | 6 - .../Prover.toml | 5 - .../src/main.nr | 29 - .../higher_order_functions/src/main.nr | 2 +- .../verify_honk_proof/Nargo.toml | 6 - .../verify_honk_proof/Prover.toml | 4 - .../verify_honk_proof/src/main.nr | 21 - noir/noir-repo/tooling/lsp/src/lib.rs | 2 + .../tooling/lsp/src/requests/code_action.rs | 7 +- .../requests/code_action/import_or_qualify.rs | 62 +- .../code_action/remove_unused_import.rs | 3 +- .../lsp/src/requests/code_action/tests.rs | 20 +- .../tooling/lsp/src/requests/completion.rs | 9 +- .../src/requests/completion/auto_import.rs | 41 +- .../lsp/src/requests/completion/tests.rs | 554 ++++++++++++++---- .../noir-repo/tooling/lsp/src/requests/mod.rs | 2 +- noir/noir-repo/tooling/lsp/src/tests.rs | 33 ++ .../tooling/lsp/src/use_segment_positions.rs | 336 +++++++++++ .../tooling/nargo/src/ops/execute.rs | 66 ++- noir/noir-repo/tooling/nargo/src/ops/mod.rs | 2 +- noir/noir-repo/tooling/nargo_cli/Cargo.toml | 1 + .../tooling/nargo_cli/tests/stdlib-tests.rs | 20 +- .../noir-repo/tooling/nargo_fmt/src/chunks.rs | 70 ++- .../src/formatter/comments_and_whitespace.rs | 4 +- .../nargo_fmt/src/formatter/expression.rs | 147 ++++- .../nargo_fmt/src/formatter/statement.rs | 6 +- .../nargo_fmt/src/formatter/use_tree.rs | 2 +- .../nargo_fmt/src/formatter/use_tree_merge.rs | 2 +- .../nargo_fmt/tests/expected/contract.nr | 2 +- .../tooling/nargo_fmt/tests/expected/tuple.nr | 24 +- .../noir-repo/tooling/noirc_abi_wasm/build.sh | 2 +- noir/noir-repo/tooling/profiler/Cargo.toml | 4 + .../src/cli/execution_flamegraph_cmd.rs | 96 +++ .../profiler/src/cli/gates_flamegraph_cmd.rs | 2 +- .../noir-repo/tooling/profiler/src/cli/mod.rs | 11 +- .../src/cli/opcodes_flamegraph_cmd.rs | 4 +- .../tooling/profiler/src/flamegraph.rs | 87 ++- noir/noir-repo/tooling/profiler/src/fs.rs | 29 +- noir/noir-repo/yarn.lock | 13 +- 83 files changed, 2605 insertions(+), 560 deletions(-) create mode 100644 noir/noir-repo/acvm-repo/acvm/src/compiler/optimizers/merge_expressions.rs create mode 100644 noir/noir-repo/compiler/noirc_frontend/src/tests/aliases.rs delete mode 100644 noir/noir-repo/test_programs/execution_success/double_verify_honk_proof/Nargo.toml delete mode 100644 noir/noir-repo/test_programs/execution_success/double_verify_honk_proof/Prover.toml delete mode 100644 noir/noir-repo/test_programs/execution_success/double_verify_honk_proof/src/main.nr delete mode 100644 noir/noir-repo/test_programs/execution_success/double_verify_honk_proof_recursive/Nargo.toml delete mode 100644 noir/noir-repo/test_programs/execution_success/double_verify_honk_proof_recursive/Prover.toml delete mode 100644 noir/noir-repo/test_programs/execution_success/double_verify_honk_proof_recursive/src/main.nr delete mode 100644 noir/noir-repo/test_programs/execution_success/verify_honk_proof/Nargo.toml delete mode 100644 noir/noir-repo/test_programs/execution_success/verify_honk_proof/Prover.toml delete mode 100644 noir/noir-repo/test_programs/execution_success/verify_honk_proof/src/main.nr create mode 100644 noir/noir-repo/tooling/lsp/src/tests.rs create mode 100644 noir/noir-repo/tooling/lsp/src/use_segment_positions.rs create mode 100644 noir/noir-repo/tooling/profiler/src/cli/execution_flamegraph_cmd.rs diff --git a/.noir-sync-commit b/.noir-sync-commit index 8bf1f2ff4b0..317dda89589 100644 --- a/.noir-sync-commit +++ b/.noir-sync-commit @@ -1 +1 @@ -598230d9427cf988fc6da8fe9e1eb2b7c00a2fa6 +2f376100d3ee7ab519d6ea30153395bb3e7af7b1 diff --git a/noir/noir-repo/Cargo.lock b/noir/noir-repo/Cargo.lock index 3bfffca46e5..3add28d3939 100644 --- a/noir/noir-repo/Cargo.lock +++ b/noir/noir-repo/Cargo.lock @@ -2587,6 +2587,7 @@ dependencies = [ "termcolor", "termion", "test-binary", + "test-case", "thiserror", "tokio", "tokio-util 0.7.10", @@ -2762,12 +2763,15 @@ name = "noir_profiler" version = "0.36.0" dependencies = [ "acir", + "bn254_blackbox_solver", "clap", "color-eyre", "const_format", "fm", + "fxhash", "im", "inferno", + "nargo", "noirc_abi", "noirc_artifacts", "noirc_driver", @@ -4420,6 +4424,39 @@ dependencies = [ "thiserror", ] +[[package]] +name = "test-case" +version = "3.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb2550dd13afcd286853192af8601920d959b14c401fcece38071d53bf0768a8" +dependencies = [ + "test-case-macros", +] + +[[package]] +name = "test-case-core" +version = "3.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adcb7fd841cd518e279be3d5a3eb0636409487998a4aff22f3de87b81e88384f" +dependencies = [ + "cfg-if 1.0.0", + "proc-macro2", + "quote", + "syn 2.0.64", +] + +[[package]] +name = "test-case-macros" +version = "3.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.64", + "test-case-core", +] + [[package]] name = "textwrap" version = "0.13.4" diff --git a/noir/noir-repo/Cargo.toml b/noir/noir-repo/Cargo.toml index 36b4d4c2ce1..222e7dce859 100644 --- a/noir/noir-repo/Cargo.toml +++ b/noir/noir-repo/Cargo.toml @@ -146,6 +146,7 @@ num-bigint = "0.4" num-traits = "0.2" similar-asserts = "1.5.0" tempfile = "3.6.0" +test-case = "3.3.1" jsonrpc = { version = "0.16.0", features = ["minreq_http"] } flate2 = "1.0.24" color-eyre = "0.6.2" diff --git a/noir/noir-repo/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs b/noir/noir-repo/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs index e06286d179e..fa51caf5155 100644 --- a/noir/noir-repo/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs +++ b/noir/noir-repo/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs @@ -1,3 +1,5 @@ +use std::collections::BTreeSet; + use crate::native_types::Witness; use crate::{AcirField, BlackBoxFunc}; @@ -389,6 +391,16 @@ impl BlackBoxFuncCall { BlackBoxFuncCall::BigIntToLeBytes { outputs, .. } => outputs.to_vec(), } } + + pub fn get_input_witnesses(&self) -> BTreeSet { + let mut result = BTreeSet::new(); + for input in self.get_inputs_vec() { + if let ConstantOrWitnessEnum::Witness(w) = input.input() { + result.insert(w); + } + } + result + } } const ABBREVIATION_LIMIT: usize = 5; diff --git a/noir/noir-repo/acvm-repo/acvm/src/compiler/optimizers/merge_expressions.rs b/noir/noir-repo/acvm-repo/acvm/src/compiler/optimizers/merge_expressions.rs new file mode 100644 index 00000000000..ddf86f60f77 --- /dev/null +++ b/noir/noir-repo/acvm-repo/acvm/src/compiler/optimizers/merge_expressions.rs @@ -0,0 +1,202 @@ +use std::collections::{BTreeMap, BTreeSet, HashMap}; + +use acir::{ + circuit::{brillig::BrilligInputs, directives::Directive, opcodes::BlockId, Circuit, Opcode}, + native_types::{Expression, Witness}, + AcirField, +}; + +pub(crate) struct MergeExpressionsOptimizer { + resolved_blocks: HashMap>, +} + +impl MergeExpressionsOptimizer { + pub(crate) fn new() -> Self { + MergeExpressionsOptimizer { resolved_blocks: HashMap::new() } + } + /// This pass analyzes the circuit and identifies intermediate variables that are + /// only used in two gates. It then merges the gate that produces the + /// intermediate variable into the second one that uses it + /// Note: This pass is only relevant for backends that can handle unlimited width + pub(crate) fn eliminate_intermediate_variable( + &mut self, + circuit: &Circuit, + acir_opcode_positions: Vec, + ) -> (Vec>, Vec) { + // Keep track, for each witness, of the gates that use it + let circuit_inputs = circuit.circuit_arguments(); + self.resolved_blocks = HashMap::new(); + let mut used_witness: BTreeMap> = BTreeMap::new(); + for (i, opcode) in circuit.opcodes.iter().enumerate() { + let witnesses = self.witness_inputs(opcode); + if let Opcode::MemoryInit { block_id, .. } = opcode { + self.resolved_blocks.insert(*block_id, witnesses.clone()); + } + for w in witnesses { + // We do not simplify circuit inputs + if !circuit_inputs.contains(&w) { + used_witness.entry(w).or_default().insert(i); + } + } + } + + let mut modified_gates: HashMap> = HashMap::new(); + let mut new_circuit = Vec::new(); + let mut new_acir_opcode_positions = Vec::new(); + // For each opcode, try to get a target opcode to merge with + for (i, opcode) in circuit.opcodes.iter().enumerate() { + if !matches!(opcode, Opcode::AssertZero(_)) { + new_circuit.push(opcode.clone()); + new_acir_opcode_positions.push(acir_opcode_positions[i]); + continue; + } + let opcode = modified_gates.get(&i).unwrap_or(opcode).clone(); + let mut to_keep = true; + let input_witnesses = self.witness_inputs(&opcode); + for w in input_witnesses.clone() { + let empty_gates = BTreeSet::new(); + let gates_using_w = used_witness.get(&w).unwrap_or(&empty_gates); + // We only consider witness which are used in exactly two arithmetic gates + if gates_using_w.len() == 2 { + let gates_using_w: Vec<_> = gates_using_w.iter().collect(); + let mut b = *gates_using_w[1]; + if b == i { + b = *gates_using_w[0]; + } else { + // sanity check + assert!(i == *gates_using_w[0]); + } + let second_gate = modified_gates.get(&b).unwrap_or(&circuit.opcodes[b]).clone(); + if let (Opcode::AssertZero(expr_define), Opcode::AssertZero(expr_use)) = + (opcode.clone(), second_gate) + { + if let Some(expr) = Self::merge(&expr_use, &expr_define, w) { + // sanity check + assert!(i < b); + modified_gates.insert(b, Opcode::AssertZero(expr)); + to_keep = false; + // Update the 'used_witness' map to account for the merge. + for w2 in Self::expr_wit(&expr_define) { + if !circuit_inputs.contains(&w2) { + let mut v = used_witness[&w2].clone(); + v.insert(b); + v.remove(&i); + used_witness.insert(w2, v); + } + } + // We need to stop here and continue with the next opcode + // because the merge invalidate the current opcode + break; + } + } + } + } + + if to_keep { + if modified_gates.contains_key(&i) { + new_circuit.push(modified_gates[&i].clone()); + } else { + new_circuit.push(opcode.clone()); + } + new_acir_opcode_positions.push(acir_opcode_positions[i]); + } + } + (new_circuit, new_acir_opcode_positions) + } + + fn expr_wit(expr: &Expression) -> BTreeSet { + let mut result = BTreeSet::new(); + result.extend(expr.mul_terms.iter().flat_map(|i| vec![i.1, i.2])); + result.extend(expr.linear_combinations.iter().map(|i| i.1)); + result + } + + fn brillig_input_wit(&self, input: &BrilligInputs) -> BTreeSet { + let mut result = BTreeSet::new(); + match input { + BrilligInputs::Single(expr) => { + result.extend(Self::expr_wit(expr)); + } + BrilligInputs::Array(exprs) => { + for expr in exprs { + result.extend(Self::expr_wit(expr)); + } + } + BrilligInputs::MemoryArray(block_id) => { + let witnesses = self.resolved_blocks.get(block_id).expect("Unknown block id"); + result.extend(witnesses); + } + } + result + } + + // Returns the input witnesses used by the opcode + fn witness_inputs(&self, opcode: &Opcode) -> BTreeSet { + let mut witnesses = BTreeSet::new(); + match opcode { + Opcode::AssertZero(expr) => Self::expr_wit(expr), + Opcode::BlackBoxFuncCall(bb_func) => bb_func.get_input_witnesses(), + Opcode::Directive(Directive::ToLeRadix { a, .. }) => Self::expr_wit(a), + Opcode::MemoryOp { block_id: _, op, predicate } => { + //index et value, et predicate + let mut witnesses = BTreeSet::new(); + witnesses.extend(Self::expr_wit(&op.index)); + witnesses.extend(Self::expr_wit(&op.value)); + if let Some(p) = predicate { + witnesses.extend(Self::expr_wit(p)); + } + witnesses + } + + Opcode::MemoryInit { block_id: _, init, block_type: _ } => { + init.iter().cloned().collect() + } + Opcode::BrilligCall { inputs, .. } => { + for i in inputs { + witnesses.extend(self.brillig_input_wit(i)); + } + witnesses + } + Opcode::Call { id: _, inputs, outputs: _, predicate } => { + for i in inputs { + witnesses.insert(*i); + } + if let Some(p) = predicate { + witnesses.extend(Self::expr_wit(p)); + } + witnesses + } + } + } + + // Merge 'expr' into 'target' via Gaussian elimination on 'w' + // Returns None if the expressions cannot be merged + fn merge( + target: &Expression, + expr: &Expression, + w: Witness, + ) -> Option> { + // Check that the witness is not part of multiplication terms + for m in &target.mul_terms { + if m.1 == w || m.2 == w { + return None; + } + } + for m in &expr.mul_terms { + if m.1 == w || m.2 == w { + return None; + } + } + + for k in &target.linear_combinations { + if k.1 == w { + for i in &expr.linear_combinations { + if i.1 == w { + return Some(target.add_mul(-(k.0 / i.0), expr)); + } + } + } + } + None + } +} diff --git a/noir/noir-repo/acvm-repo/acvm/src/compiler/optimizers/mod.rs b/noir/noir-repo/acvm-repo/acvm/src/compiler/optimizers/mod.rs index e20ad97a108..1947a80dc35 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/compiler/optimizers/mod.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/compiler/optimizers/mod.rs @@ -5,10 +5,12 @@ use acir::{ // mod constant_backpropagation; mod general; +mod merge_expressions; mod redundant_range; mod unused_memory; pub(crate) use general::GeneralOptimizer; +pub(crate) use merge_expressions::MergeExpressionsOptimizer; pub(crate) use redundant_range::RangeOptimizer; use tracing::info; diff --git a/noir/noir-repo/acvm-repo/acvm/src/compiler/transformers/mod.rs b/noir/noir-repo/acvm-repo/acvm/src/compiler/transformers/mod.rs index 4e29681cbed..b11d054a57b 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/compiler/transformers/mod.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/compiler/transformers/mod.rs @@ -10,7 +10,9 @@ mod csat; pub(crate) use csat::CSatTransformer; pub use csat::MIN_EXPRESSION_WIDTH; -use super::{transform_assert_messages, AcirTransformationMap}; +use super::{ + optimizers::MergeExpressionsOptimizer, transform_assert_messages, AcirTransformationMap, +}; /// Applies [`ProofSystemCompiler`][crate::ProofSystemCompiler] specific optimizations to a [`Circuit`]. pub fn transform( @@ -166,6 +168,16 @@ pub(super) fn transform_internal( // The transformer does not add new public inputs ..acir }; - + let mut merge_optimizer = MergeExpressionsOptimizer::new(); + let (opcodes, new_acir_opcode_positions) = + merge_optimizer.eliminate_intermediate_variable(&acir, new_acir_opcode_positions); + // n.b. we do not update current_witness_index after the eliminate_intermediate_variable pass, the real index could be less. + let acir = Circuit { + current_witness_index, + expression_width, + opcodes, + // The optimizer does not add new public inputs + ..acir + }; (acir, new_acir_opcode_positions) } diff --git a/noir/noir-repo/acvm-repo/acvm/src/pwg/brillig.rs b/noir/noir-repo/acvm-repo/acvm/src/pwg/brillig.rs index 5ec3224dbaa..dffa45dbd7a 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/pwg/brillig.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/pwg/brillig.rs @@ -12,7 +12,7 @@ use acir::{ AcirField, }; use acvm_blackbox_solver::BlackBoxFunctionSolver; -use brillig_vm::{FailureReason, MemoryValue, VMStatus, VM}; +use brillig_vm::{BrilligProfilingSamples, FailureReason, MemoryValue, VMStatus, VM}; use serde::{Deserialize, Serialize}; use crate::{pwg::OpcodeNotSolvable, OpcodeResolutionError}; @@ -58,6 +58,7 @@ impl<'b, B: BlackBoxFunctionSolver, F: AcirField> BrilligSolver<'b, F, B> { /// Constructs a solver for a Brillig block given the bytecode and initial /// witness. + #[allow(clippy::too_many_arguments)] pub(crate) fn new_call( initial_witness: &WitnessMap, memory: &HashMap>, @@ -66,9 +67,16 @@ impl<'b, B: BlackBoxFunctionSolver, F: AcirField> BrilligSolver<'b, F, B> { bb_solver: &'b B, acir_index: usize, brillig_function_id: BrilligFunctionId, + profiling_active: bool, ) -> Result> { - let vm = - Self::setup_brillig_vm(initial_witness, memory, inputs, brillig_bytecode, bb_solver)?; + let vm = Self::setup_brillig_vm( + initial_witness, + memory, + inputs, + brillig_bytecode, + bb_solver, + profiling_active, + )?; Ok(Self { vm, acir_index, function_id: brillig_function_id }) } @@ -78,6 +86,7 @@ impl<'b, B: BlackBoxFunctionSolver, F: AcirField> BrilligSolver<'b, F, B> { inputs: &[BrilligInputs], brillig_bytecode: &'b [BrilligOpcode], bb_solver: &'b B, + profiling_active: bool, ) -> Result, OpcodeResolutionError> { // Set input values let mut calldata: Vec = Vec::new(); @@ -125,7 +134,7 @@ impl<'b, B: BlackBoxFunctionSolver, F: AcirField> BrilligSolver<'b, F, B> { // Instantiate a Brillig VM given the solved calldata // along with the Brillig bytecode. - let vm = VM::new(calldata, brillig_bytecode, vec![], bb_solver); + let vm = VM::new(calldata, brillig_bytecode, vec![], bb_solver, profiling_active); Ok(vm) } @@ -203,6 +212,25 @@ impl<'b, B: BlackBoxFunctionSolver, F: AcirField> BrilligSolver<'b, F, B> { self, witness: &mut WitnessMap, outputs: &[BrilligOutputs], + ) -> Result<(), OpcodeResolutionError> { + assert!(!self.vm.is_profiling_active(), "Expected VM profiling to not be active"); + self.finalize_inner(witness, outputs) + } + + pub(crate) fn finalize_with_profiling( + mut self, + witness: &mut WitnessMap, + outputs: &[BrilligOutputs], + ) -> Result> { + assert!(self.vm.is_profiling_active(), "Expected VM profiling to be active"); + self.finalize_inner(witness, outputs)?; + Ok(self.vm.take_profiling_samples()) + } + + fn finalize_inner( + &self, + witness: &mut WitnessMap, + outputs: &[BrilligOutputs], ) -> Result<(), OpcodeResolutionError> { // Finish the Brillig execution by writing the outputs to the witness map let vm_status = self.vm.get_status(); diff --git a/noir/noir-repo/acvm-repo/acvm/src/pwg/mod.rs b/noir/noir-repo/acvm-repo/acvm/src/pwg/mod.rs index c73893ceea6..fa3498da613 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/pwg/mod.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/pwg/mod.rs @@ -168,6 +168,14 @@ impl From for OpcodeResolutionError { } } +pub type ProfilingSamples = Vec; + +#[derive(Default)] +pub struct ProfilingSample { + pub call_stack: Vec, + pub brillig_function_id: Option, +} + pub struct ACVM<'a, F, B: BlackBoxFunctionSolver> { status: ACVMStatus, @@ -198,6 +206,10 @@ pub struct ACVM<'a, F, B: BlackBoxFunctionSolver> { unconstrained_functions: &'a [BrilligBytecode], assertion_payloads: &'a [(OpcodeLocation, AssertionPayload)], + + profiling_active: bool, + + profiling_samples: ProfilingSamples, } impl<'a, F: AcirField, B: BlackBoxFunctionSolver> ACVM<'a, F, B> { @@ -222,9 +234,16 @@ impl<'a, F: AcirField, B: BlackBoxFunctionSolver> ACVM<'a, F, B> { acir_call_results: Vec::default(), unconstrained_functions, assertion_payloads, + profiling_active: false, + profiling_samples: Vec::new(), } } + // Enable profiling + pub fn with_profiler(&mut self, profiling_active: bool) { + self.profiling_active = profiling_active; + } + /// Returns a reference to the current state of the ACVM's [`WitnessMap`]. /// /// Once execution has completed, the witness map can be extracted using [`ACVM::finalize`] @@ -246,6 +265,10 @@ impl<'a, F: AcirField, B: BlackBoxFunctionSolver> ACVM<'a, F, B> { self.instruction_pointer } + pub fn take_profiling_samples(&mut self) -> ProfilingSamples { + std::mem::take(&mut self.profiling_samples) + } + /// Finalize the ACVM execution, returning the resulting [`WitnessMap`]. pub fn finalize(self) -> WitnessMap { if self.status != ACVMStatus::Solved { @@ -503,6 +526,7 @@ impl<'a, F: AcirField, B: BlackBoxFunctionSolver> ACVM<'a, F, B> { self.backend, self.instruction_pointer, *id, + self.profiling_active, )?, }; @@ -519,7 +543,28 @@ impl<'a, F: AcirField, B: BlackBoxFunctionSolver> ACVM<'a, F, B> { } BrilligSolverStatus::Finished => { // Write execution outputs - solver.finalize(&mut self.witness_map, outputs)?; + if self.profiling_active { + let profiling_info = + solver.finalize_with_profiling(&mut self.witness_map, outputs)?; + profiling_info.into_iter().for_each(|sample| { + let mapped = + sample.call_stack.into_iter().map(|loc| OpcodeLocation::Brillig { + acir_index: self.instruction_pointer, + brillig_index: loc, + }); + self.profiling_samples.push(ProfilingSample { + call_stack: std::iter::once(OpcodeLocation::Acir( + self.instruction_pointer, + )) + .chain(mapped) + .collect(), + brillig_function_id: Some(*id), + }); + }); + } else { + solver.finalize(&mut self.witness_map, outputs)?; + } + Ok(None) } } @@ -575,6 +620,7 @@ impl<'a, F: AcirField, B: BlackBoxFunctionSolver> ACVM<'a, F, B> { self.backend, self.instruction_pointer, *id, + self.profiling_active, ); match solver { Ok(solver) => StepResult::IntoBrillig(solver), diff --git a/noir/noir-repo/acvm-repo/acvm_js/build.sh b/noir/noir-repo/acvm-repo/acvm_js/build.sh index c07d2d8a4c1..16fb26e55db 100755 --- a/noir/noir-repo/acvm-repo/acvm_js/build.sh +++ b/noir/noir-repo/acvm-repo/acvm_js/build.sh @@ -25,7 +25,7 @@ function run_if_available { require_command jq require_command cargo require_command wasm-bindgen -#require_command wasm-opt +require_command wasm-opt self_path=$(dirname "$(readlink -f "$0")") pname=$(cargo read-manifest | jq -r '.name') diff --git a/noir/noir-repo/acvm-repo/brillig_vm/src/lib.rs b/noir/noir-repo/acvm-repo/brillig_vm/src/lib.rs index 1e5ad84eb8f..4d5ce4203f9 100644 --- a/noir/noir-repo/acvm-repo/brillig_vm/src/lib.rs +++ b/noir/noir-repo/acvm-repo/brillig_vm/src/lib.rs @@ -63,6 +63,15 @@ pub enum VMStatus { }, } +// A sample for each opcode that was executed. +pub type BrilligProfilingSamples = Vec; + +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct BrilligProfilingSample { + // The call stack when processing a given opcode. + pub call_stack: Vec, +} + #[derive(Debug, PartialEq, Eq, Clone)] /// VM encapsulates the state of the Brillig VM during execution. pub struct VM<'a, F, B: BlackBoxFunctionSolver> { @@ -88,6 +97,10 @@ pub struct VM<'a, F, B: BlackBoxFunctionSolver> { black_box_solver: &'a B, // The solver for big integers bigint_solver: BrilligBigintSolver, + // Flag that determines whether we want to profile VM. + profiling_active: bool, + // Samples for profiling the VM execution. + profiling_samples: BrilligProfilingSamples, } impl<'a, F: AcirField, B: BlackBoxFunctionSolver> VM<'a, F, B> { @@ -97,6 +110,7 @@ impl<'a, F: AcirField, B: BlackBoxFunctionSolver> VM<'a, F, B> { bytecode: &'a [Opcode], foreign_call_results: Vec>, black_box_solver: &'a B, + profiling_active: bool, ) -> Self { Self { calldata, @@ -109,9 +123,19 @@ impl<'a, F: AcirField, B: BlackBoxFunctionSolver> VM<'a, F, B> { call_stack: Vec::new(), black_box_solver, bigint_solver: Default::default(), + profiling_active, + profiling_samples: Vec::with_capacity(bytecode.len()), } } + pub fn is_profiling_active(&self) -> bool { + self.profiling_active + } + + pub fn take_profiling_samples(&mut self) -> BrilligProfilingSamples { + std::mem::take(&mut self.profiling_samples) + } + /// Updates the current status of the VM. /// Returns the given status. fn status(&mut self, status: VMStatus) -> VMStatus { @@ -196,6 +220,15 @@ impl<'a, F: AcirField, B: BlackBoxFunctionSolver> VM<'a, F, B> { /// Process a single opcode and modify the program counter. pub fn process_opcode(&mut self) -> VMStatus { + if self.profiling_active { + let call_stack: Vec = self.get_call_stack(); + self.profiling_samples.push(BrilligProfilingSample { call_stack }); + } + + self.process_opcode_internal() + } + + fn process_opcode_internal(&mut self) -> VMStatus { let opcode = &self.bytecode[self.program_counter]; match opcode { Opcode::BinaryFieldOp { op, lhs, rhs, destination: result } => { @@ -813,7 +846,7 @@ mod tests { }]; // Start VM - let mut vm = VM::new(calldata, &opcodes, vec![], &StubbedBlackBoxSolver); + let mut vm = VM::new(calldata, &opcodes, vec![], &StubbedBlackBoxSolver, false); let status = vm.process_opcode(); assert_eq!(status, VMStatus::Finished { return_data_offset: 0, return_data_size: 0 }); @@ -863,7 +896,7 @@ mod tests { Opcode::JumpIf { condition: destination, location: 6 }, ]; - let mut vm = VM::new(calldata, &opcodes, vec![], &StubbedBlackBoxSolver); + let mut vm = VM::new(calldata, &opcodes, vec![], &StubbedBlackBoxSolver, false); let status = vm.process_opcode(); assert_eq!(status, VMStatus::InProgress); @@ -921,7 +954,7 @@ mod tests { }, ]; - let mut vm = VM::new(calldata, &opcodes, vec![], &StubbedBlackBoxSolver); + let mut vm = VM::new(calldata, &opcodes, vec![], &StubbedBlackBoxSolver, false); let status = vm.process_opcode(); assert_eq!(status, VMStatus::InProgress); @@ -982,7 +1015,7 @@ mod tests { }, Opcode::Stop { return_data_offset: 1, return_data_size: 1 }, ]; - let mut vm = VM::new(calldata, opcodes, vec![], &StubbedBlackBoxSolver); + let mut vm = VM::new(calldata, opcodes, vec![], &StubbedBlackBoxSolver, false); let status = vm.process_opcode(); assert_eq!(status, VMStatus::InProgress); @@ -1033,7 +1066,7 @@ mod tests { }, Opcode::Stop { return_data_offset: 1, return_data_size: 1 }, ]; - let mut vm = VM::new(calldata, opcodes, vec![], &StubbedBlackBoxSolver); + let mut vm = VM::new(calldata, opcodes, vec![], &StubbedBlackBoxSolver, false); let status = vm.process_opcode(); assert_eq!(status, VMStatus::InProgress); @@ -1079,7 +1112,7 @@ mod tests { }, Opcode::Mov { destination: MemoryAddress::direct(2), source: MemoryAddress::direct(0) }, ]; - let mut vm = VM::new(calldata, opcodes, vec![], &StubbedBlackBoxSolver); + let mut vm = VM::new(calldata, opcodes, vec![], &StubbedBlackBoxSolver, false); let status = vm.process_opcode(); assert_eq!(status, VMStatus::InProgress); @@ -1144,7 +1177,7 @@ mod tests { condition: MemoryAddress::direct(1), }, ]; - let mut vm = VM::new(calldata, opcodes, vec![], &StubbedBlackBoxSolver); + let mut vm = VM::new(calldata, opcodes, vec![], &StubbedBlackBoxSolver, false); let status = vm.process_opcode(); assert_eq!(status, VMStatus::InProgress); @@ -1240,7 +1273,7 @@ mod tests { .chain(cast_opcodes) .chain([equal_opcode, not_equal_opcode, less_than_opcode, less_than_equal_opcode]) .collect(); - let mut vm = VM::new(calldata, &opcodes, vec![], &StubbedBlackBoxSolver); + let mut vm = VM::new(calldata, &opcodes, vec![], &StubbedBlackBoxSolver, false); // Calldata copy let status = vm.process_opcode(); @@ -1368,7 +1401,7 @@ mod tests { value: FieldElement::from(27_usize), }, ]; - let mut vm = VM::new(vec![], opcodes, vec![], &StubbedBlackBoxSolver); + let mut vm = VM::new(vec![], opcodes, vec![], &StubbedBlackBoxSolver, false); let status = vm.process_opcode(); assert_eq!(status, VMStatus::InProgress); @@ -1592,7 +1625,7 @@ mod tests { calldata: Vec, opcodes: &[Opcode], ) -> VM<'_, F, StubbedBlackBoxSolver> { - let mut vm = VM::new(calldata, opcodes, vec![], &StubbedBlackBoxSolver); + let mut vm = VM::new(calldata, opcodes, vec![], &StubbedBlackBoxSolver, false); brillig_execute(&mut vm); assert_eq!(vm.call_stack, vec![]); vm @@ -2271,7 +2304,7 @@ mod tests { }, ]; - let mut vm = VM::new(calldata, &opcodes, vec![], &StubbedBlackBoxSolver); + let mut vm = VM::new(calldata, &opcodes, vec![], &StubbedBlackBoxSolver, false); vm.process_opcode(); vm.process_opcode(); diff --git a/noir/noir-repo/compiler/integration-tests/package.json b/noir/noir-repo/compiler/integration-tests/package.json index e33179f31e7..62ae699fc4e 100644 --- a/noir/noir-repo/compiler/integration-tests/package.json +++ b/noir/noir-repo/compiler/integration-tests/package.json @@ -13,7 +13,7 @@ "lint": "NODE_NO_WARNINGS=1 eslint . --ext .ts --ignore-path ./.eslintignore --max-warnings 0" }, "dependencies": { - "@aztec/bb.js": "portal:../../../../barretenberg/ts", + "@aztec/bb.js": "0.60.0", "@noir-lang/noir_js": "workspace:*", "@noir-lang/noir_wasm": "workspace:*", "@nomicfoundation/hardhat-chai-matchers": "^2.0.0", diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir.rs b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir.rs index 4964ff27f60..416f0300508 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir.rs @@ -233,7 +233,8 @@ pub(crate) mod tests { calldata: Vec, bytecode: &[BrilligOpcode], ) -> (VM<'_, FieldElement, DummyBlackBoxSolver>, usize, usize) { - let mut vm = VM::new(calldata, bytecode, vec![], &DummyBlackBoxSolver); + let profiling_active = false; + let mut vm = VM::new(calldata, bytecode, vec![], &DummyBlackBoxSolver, profiling_active); let status = vm.process_opcodes(); if let VMStatus::Finished { return_data_offset, return_data_size } = status { @@ -301,6 +302,7 @@ pub(crate) mod tests { &bytecode, vec![ForeignCallResult { values: vec![ForeignCallParam::Array(number_sequence)] }], &DummyBlackBoxSolver, + false, ); let status = vm.process_opcodes(); assert_eq!(status, VMStatus::Finished { return_data_offset: 0, return_data_size: 0 }); diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs index db08b906185..811b728a9d5 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs @@ -2195,7 +2195,8 @@ fn execute_brillig( // We pass a stubbed solver here as a concrete solver implies a field choice which conflicts with this function // being generic. let solver = acvm::blackbox_solver::StubbedBlackBoxSolver; - let mut vm = VM::new(calldata, code, Vec::new(), &solver); + let profiling_active = false; + let mut vm = VM::new(calldata, code, Vec::new(), &solver, profiling_active); // Run the Brillig VM on these inputs, bytecode, etc! let vm_status = vm.process_opcodes(); diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/array_set.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/array_set.rs index 6ae13bc085a..7035345436e 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/array_set.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/array_set.rs @@ -53,7 +53,9 @@ struct Context<'f> { is_brillig_runtime: bool, array_to_last_use: HashMap, instructions_that_can_be_made_mutable: HashSet, - arrays_from_load: HashSet, + // Mapping of an array that comes from a load and whether the address + // it was loaded from is a reference parameter. + arrays_from_load: HashMap, inner_nested_arrays: HashMap, } @@ -64,7 +66,7 @@ impl<'f> Context<'f> { is_brillig_runtime, array_to_last_use: HashMap::default(), instructions_that_can_be_made_mutable: HashSet::default(), - arrays_from_load: HashSet::default(), + arrays_from_load: HashMap::default(), inner_nested_arrays: HashMap::default(), } } @@ -113,9 +115,13 @@ impl<'f> Context<'f> { array_in_terminator = true; } }); - if (!self.arrays_from_load.contains(&array) || is_return_block) - && !array_in_terminator - { + if let Some(is_from_param) = self.arrays_from_load.get(&array) { + // If the array was loaded from a reference parameter, we cannot + // safely mark that array mutable as it may be shared by another value. + if !is_from_param && is_return_block { + self.instructions_that_can_be_made_mutable.insert(*instruction_id); + } + } else if !array_in_terminator { self.instructions_that_can_be_made_mutable.insert(*instruction_id); } } @@ -133,10 +139,12 @@ impl<'f> Context<'f> { } } } - Instruction::Load { .. } => { + Instruction::Load { address } => { let result = self.dfg.instruction_results(*instruction_id)[0]; if matches!(self.dfg.type_of_value(result), Array { .. } | Slice { .. }) { - self.arrays_from_load.insert(result); + let is_reference_param = + self.dfg.block_parameters(block_id).contains(address); + self.arrays_from_load.insert(result, is_reference_param); } } _ => (), diff --git a/noir/noir-repo/compiler/noirc_frontend/src/ast/statement.rs b/noir/noir-repo/compiler/noirc_frontend/src/ast/statement.rs index 038a7b76bac..a25b87b7395 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/ast/statement.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/ast/statement.rs @@ -327,6 +327,7 @@ pub enum PathKind { pub struct UseTree { pub prefix: Path, pub kind: UseTreeKind, + pub span: Span, } impl Display for UseTree { diff --git a/noir/noir-repo/compiler/noirc_frontend/src/elaborator/mod.rs b/noir/noir-repo/compiler/noirc_frontend/src/elaborator/mod.rs index 641e2d1d57e..9f56b72f4e9 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/elaborator/mod.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/elaborator/mod.rs @@ -1041,11 +1041,14 @@ impl<'context> Elaborator<'context> { self.file = trait_impl.file_id; self.local_module = trait_impl.module_id; - self.check_parent_traits_are_implemented(&trait_impl); - - self.generics = trait_impl.resolved_generics; + self.generics = trait_impl.resolved_generics.clone(); self.current_trait_impl = trait_impl.impl_id; + self.add_trait_impl_assumed_trait_implementations(trait_impl.impl_id); + self.check_trait_impl_where_clause_matches_trait_where_clause(&trait_impl); + self.check_parent_traits_are_implemented(&trait_impl); + self.remove_trait_impl_assumed_trait_implementations(trait_impl.impl_id); + for (module, function, _) in &trait_impl.methods.functions { self.local_module = *module; let errors = check_trait_impl_method_matches_declaration(self.interner, *function); @@ -1059,6 +1062,95 @@ impl<'context> Elaborator<'context> { self.generics.clear(); } + fn add_trait_impl_assumed_trait_implementations(&mut self, impl_id: Option) { + if let Some(impl_id) = impl_id { + if let Some(trait_implementation) = self.interner.try_get_trait_implementation(impl_id) + { + for trait_constrain in &trait_implementation.borrow().where_clause { + let trait_bound = &trait_constrain.trait_bound; + self.interner.add_assumed_trait_implementation( + trait_constrain.typ.clone(), + trait_bound.trait_id, + trait_bound.trait_generics.clone(), + ); + } + } + } + } + + fn remove_trait_impl_assumed_trait_implementations(&mut self, impl_id: Option) { + if let Some(impl_id) = impl_id { + if let Some(trait_implementation) = self.interner.try_get_trait_implementation(impl_id) + { + for trait_constrain in &trait_implementation.borrow().where_clause { + self.interner.remove_assumed_trait_implementations_for_trait( + trait_constrain.trait_bound.trait_id, + ); + } + } + } + } + + fn check_trait_impl_where_clause_matches_trait_where_clause( + &mut self, + trait_impl: &UnresolvedTraitImpl, + ) { + let Some(trait_id) = trait_impl.trait_id else { + return; + }; + + let Some(the_trait) = self.interner.try_get_trait(trait_id) else { + return; + }; + + if the_trait.where_clause.is_empty() { + return; + } + + let impl_trait = the_trait.name.to_string(); + let the_trait_file = the_trait.location.file; + + let mut bindings = TypeBindings::new(); + bind_ordered_generics( + &the_trait.generics, + &trait_impl.resolved_trait_generics, + &mut bindings, + ); + + // Check that each of the trait's where clause constraints is satisfied + for trait_constraint in the_trait.where_clause.clone() { + let Some(trait_constraint_trait) = + self.interner.try_get_trait(trait_constraint.trait_bound.trait_id) + else { + continue; + }; + + let trait_constraint_type = trait_constraint.typ.substitute(&bindings); + let trait_bound = &trait_constraint.trait_bound; + + if self + .interner + .try_lookup_trait_implementation( + &trait_constraint_type, + trait_bound.trait_id, + &trait_bound.trait_generics.ordered, + &trait_bound.trait_generics.named, + ) + .is_err() + { + let missing_trait = + format!("{}{}", trait_constraint_trait.name, trait_bound.trait_generics); + self.push_err(ResolverError::TraitNotImplemented { + impl_trait: impl_trait.clone(), + missing_trait, + type_missing_trait: trait_constraint_type.to_string(), + span: trait_impl.object_type.span, + missing_trait_location: Location::new(trait_bound.span, the_trait_file), + }); + } + } + } + fn check_parent_traits_are_implemented(&mut self, trait_impl: &UnresolvedTraitImpl) { let Some(trait_id) = trait_impl.trait_id else { return; @@ -1182,7 +1274,7 @@ impl<'context> Elaborator<'context> { trait_id, trait_generics, file: trait_impl.file_id, - where_clause: where_clause.clone(), + where_clause, methods, }); diff --git a/noir/noir-repo/compiler/noirc_frontend/src/elaborator/scope.rs b/noir/noir-repo/compiler/noirc_frontend/src/elaborator/scope.rs index b83a1494ab9..d38b7a50175 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/elaborator/scope.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/elaborator/scope.rs @@ -269,12 +269,26 @@ impl<'context> Elaborator<'context> { } } - match self.lookup(path) { - Ok(struct_id) => { + let span = path.span; + match self.resolve_path_or_error(path) { + Ok(ModuleDefId::TypeId(struct_id)) => { let struct_type = self.get_struct(struct_id); let generics = struct_type.borrow().instantiate(self.interner); Some(Type::Struct(struct_type, generics)) } + Ok(ModuleDefId::TypeAliasId(alias_id)) => { + let alias = self.interner.get_type_alias(alias_id); + let alias = alias.borrow(); + Some(alias.instantiate(self.interner)) + } + Ok(other) => { + self.push_err(ResolverError::Expected { + expected: StructId::description(), + got: other.as_str().to_owned(), + span, + }); + None + } Err(error) => { self.push_err(error); None diff --git a/noir/noir-repo/compiler/noirc_frontend/src/elaborator/traits.rs b/noir/noir-repo/compiler/noirc_frontend/src/elaborator/traits.rs index e877682972c..ae278616e03 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/elaborator/traits.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/elaborator/traits.rs @@ -32,6 +32,9 @@ impl<'context> Elaborator<'context> { &resolved_generics, ); + let where_clause = + this.resolve_trait_constraints(&unresolved_trait.trait_def.where_clause); + // Each associated type in this trait is also an implicit generic for associated_type in &this.interner.get_trait(*trait_id).associated_types { this.generics.push(associated_type.clone()); @@ -48,6 +51,7 @@ impl<'context> Elaborator<'context> { this.interner.update_trait(*trait_id, |trait_def| { trait_def.set_methods(methods); trait_def.set_trait_bounds(resolved_trait_bounds); + trait_def.set_where_clause(where_clause); }); }); diff --git a/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/interpreter.rs b/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/interpreter.rs index ffb759e74a2..7205242ead9 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/interpreter.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/interpreter.rs @@ -554,8 +554,8 @@ impl<'local, 'interner> Interpreter<'local, 'interner> { match &definition.kind { DefinitionKind::Function(function_id) => { let typ = self.elaborator.interner.id_type(id).follow_bindings(); - let bindings = - Rc::new(self.elaborator.interner.get_instantiation_bindings(id).clone()); + let bindings = self.elaborator.interner.try_get_instantiation_bindings(id); + let bindings = Rc::new(bindings.map_or(TypeBindings::default(), Clone::clone)); Ok(Value::Function(*function_id, typ, bindings)) } DefinitionKind::Local(_) => self.lookup(&ident), diff --git a/noir/noir-repo/compiler/noirc_frontend/src/hir_def/traits.rs b/noir/noir-repo/compiler/noirc_frontend/src/hir_def/traits.rs index 534805c2dad..6fd3c4f7a24 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/hir_def/traits.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/hir_def/traits.rs @@ -75,6 +75,8 @@ pub struct Trait { /// The resolved trait bounds (for example in `trait Foo: Bar + Baz`, this would be `Bar + Baz`) pub trait_bounds: Vec, + + pub where_clause: Vec, } #[derive(Debug)] @@ -154,6 +156,10 @@ impl Trait { self.trait_bounds = trait_bounds; } + pub fn set_where_clause(&mut self, where_clause: Vec) { + self.where_clause = where_clause; + } + pub fn find_method(&self, name: &str) -> Option { for (idx, method) in self.methods.iter().enumerate() { if &method.name == name { diff --git a/noir/noir-repo/compiler/noirc_frontend/src/hir_def/types.rs b/noir/noir-repo/compiler/noirc_frontend/src/hir_def/types.rs index fa2a455c06d..77030b0e048 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/hir_def/types.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/hir_def/types.rs @@ -590,6 +590,11 @@ impl TypeAlias { self.typ.substitute(&substitutions) } + + pub fn instantiate(&self, interner: &NodeInterner) -> Type { + let args = vecmap(&self.generics, |_| interner.next_type_variable()); + self.get_type(&args) + } } /// A shared, mutable reference to some T. diff --git a/noir/noir-repo/compiler/noirc_frontend/src/node_interner.rs b/noir/noir-repo/compiler/noirc_frontend/src/node_interner.rs index ca7e0c6aa59..2183cfba0ef 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/node_interner.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/node_interner.rs @@ -735,6 +735,7 @@ impl NodeInterner { method_ids: unresolved_trait.method_ids.clone(), associated_types, trait_bounds: Vec::new(), + where_clause: Vec::new(), }; self.traits.insert(type_id, new_trait); diff --git a/noir/noir-repo/compiler/noirc_frontend/src/parser/parser/use_tree.rs b/noir/noir-repo/compiler/noirc_frontend/src/parser/parser/use_tree.rs index bc95c04d46b..08834383f99 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/parser/parser/use_tree.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/parser/parser/use_tree.rs @@ -53,13 +53,17 @@ impl<'a> Parser<'a> { Self::parse_use_tree_in_list, ); - UseTree { prefix, kind: UseTreeKind::List(use_trees) } + UseTree { + prefix, + kind: UseTreeKind::List(use_trees), + span: self.span_since(start_span), + } } else { self.expected_token(Token::LeftBrace); - self.parse_path_use_tree_end(prefix, nested) + self.parse_path_use_tree_end(prefix, nested, start_span) } } else { - self.parse_path_use_tree_end(prefix, nested) + self.parse_path_use_tree_end(prefix, nested, start_span) } } @@ -71,6 +75,7 @@ impl<'a> Parser<'a> { return Some(UseTree { prefix: Path { segments: Vec::new(), kind: PathKind::Plain, span: start_span }, kind: UseTreeKind::Path(Ident::new("self".to_string(), start_span), None), + span: start_span, }); } @@ -89,25 +94,46 @@ impl<'a> Parser<'a> { } } - pub(super) fn parse_path_use_tree_end(&mut self, mut prefix: Path, nested: bool) -> UseTree { + pub(super) fn parse_path_use_tree_end( + &mut self, + mut prefix: Path, + nested: bool, + start_span: Span, + ) -> UseTree { if prefix.segments.is_empty() { if nested { self.expected_identifier(); } else { self.expected_label(ParsingRuleLabel::UseSegment); } - UseTree { prefix, kind: UseTreeKind::Path(Ident::default(), None) } + UseTree { + prefix, + kind: UseTreeKind::Path(Ident::default(), None), + span: self.span_since(start_span), + } } else { let ident = prefix.segments.pop().unwrap().ident; if self.eat_keyword(Keyword::As) { if let Some(alias) = self.eat_ident() { - UseTree { prefix, kind: UseTreeKind::Path(ident, Some(alias)) } + UseTree { + prefix, + kind: UseTreeKind::Path(ident, Some(alias)), + span: self.span_since(start_span), + } } else { self.expected_identifier(); - UseTree { prefix, kind: UseTreeKind::Path(ident, None) } + UseTree { + prefix, + kind: UseTreeKind::Path(ident, None), + span: self.span_since(start_span), + } } } else { - UseTree { prefix, kind: UseTreeKind::Path(ident, None) } + UseTree { + prefix, + kind: UseTreeKind::Path(ident, None), + span: self.span_since(start_span), + } } } } diff --git a/noir/noir-repo/compiler/noirc_frontend/src/tests.rs b/noir/noir-repo/compiler/noirc_frontend/src/tests.rs index ce4ad4d1bb9..56c4b5e9a12 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/tests.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/tests.rs @@ -1,7 +1,9 @@ #![cfg(test)] +mod aliases; mod bound_checks; mod imports; +mod metaprogramming; mod name_shadowing; mod references; mod traits; @@ -2969,9 +2971,7 @@ fn uses_self_type_in_trait_where_clause() { } } - struct Bar { - - } + struct Bar {} impl Foo for Bar { @@ -2983,12 +2983,17 @@ fn uses_self_type_in_trait_where_clause() { "#; let errors = get_program_errors(src); - assert_eq!(errors.len(), 1); + assert_eq!(errors.len(), 2); + + let CompilationError::ResolverError(ResolverError::TraitNotImplemented { .. }) = &errors[0].0 + else { + panic!("Expected a trait not implemented error, got {:?}", errors[0].0); + }; let CompilationError::TypeError(TypeCheckError::UnresolvedMethodCall { method_name, .. }) = - &errors[0].0 + &errors[1].0 else { - panic!("Expected an unresolved method call error, got {:?}", errors[0].0); + panic!("Expected an unresolved method call error, got {:?}", errors[1].0); }; assert_eq!(method_name, "trait_func"); @@ -3541,3 +3546,19 @@ fn uses_self_in_import() { "#; assert_no_errors(src); } + +#[test] +fn alias_in_let_pattern() { + let src = r#" + struct Foo { x: T } + + type Bar = Foo; + + fn main() { + let Bar { x } = Foo { x: [0] }; + // This is just to show the compiler knows this is an array. + let _: [Field; 1] = x; + } + "#; + assert_no_errors(src); +} diff --git a/noir/noir-repo/compiler/noirc_frontend/src/tests/aliases.rs b/noir/noir-repo/compiler/noirc_frontend/src/tests/aliases.rs new file mode 100644 index 00000000000..5239abcb366 --- /dev/null +++ b/noir/noir-repo/compiler/noirc_frontend/src/tests/aliases.rs @@ -0,0 +1,33 @@ +use super::assert_no_errors; + +#[test] +fn allows_usage_of_type_alias_as_argument_type() { + let src = r#" + type Foo = Field; + + fn accepts_a_foo(x: Foo) { + assert_eq(x, 42); + } + + fn main() { + accepts_a_foo(42); + } + "#; + assert_no_errors(src); +} + +#[test] +fn allows_usage_of_type_alias_as_return_type() { + let src = r#" + type Foo = Field; + + fn returns_a_foo() -> Foo { + 42 + } + + fn main() { + let _ = returns_a_foo(); + } + "#; + assert_no_errors(src); +} diff --git a/noir/noir-repo/compiler/noirc_frontend/src/tests/metaprogramming.rs b/noir/noir-repo/compiler/noirc_frontend/src/tests/metaprogramming.rs index ec52310b3d6..82c40203244 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/tests/metaprogramming.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/tests/metaprogramming.rs @@ -1,6 +1,18 @@ -use crate::hir::def_collector::dc_crate::CompilationError; +use noirc_errors::Spanned; -use super::get_program_errors; +use crate::{ + ast::Ident, + hir::{ + def_collector::{ + dc_crate::CompilationError, + errors::{DefCollectorErrorKind, DuplicateType}, + }, + resolution::errors::ResolverError, + type_check::TypeCheckError, + }, +}; + +use super::{assert_no_errors, get_program_errors}; // Regression for #5388 #[test] @@ -74,3 +86,58 @@ fn unquoted_integer_as_integer_token() { assert_no_errors(src); } + +#[test] +fn allows_references_to_structs_generated_by_macros() { + let src = r#" + comptime fn make_new_struct(_s: StructDefinition) -> Quoted { + quote { struct Bar {} } + } + + #[make_new_struct] + struct Foo {} + + fn main() { + let _ = Foo {}; + let _ = Bar {}; + } + "#; + + assert_no_errors(src); +} + +#[test] +fn errors_if_macros_inject_functions_with_name_collisions() { + let src = r#" + comptime fn make_colliding_functions(_s: StructDefinition) -> Quoted { + quote { + fn foo() {} + } + } + + #[make_colliding_functions] + struct Foo {} + + #[make_colliding_functions] + struct Bar {} + + fn main() { + let _ = Foo {}; + let _ = Bar {}; + foo(); + } + "#; + + let errors = get_program_errors(src); + assert_eq!(errors.len(), 1); + assert!(matches!( + &errors[0].0, + CompilationError::DefinitionError( + DefCollectorErrorKind::Duplicate { + typ: DuplicateType::Function, + first_def: Ident(Spanned { contents, .. }), + .. + }, + ) if contents == "foo" + )); +} diff --git a/noir/noir-repo/compiler/noirc_frontend/src/tests/traits.rs b/noir/noir-repo/compiler/noirc_frontend/src/tests/traits.rs index ee84cc0e890..88138ecde4d 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/tests/traits.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/tests/traits.rs @@ -148,3 +148,116 @@ fn trait_inheritance_missing_parent_implementation() { assert_eq!(typ, "Struct"); assert_eq!(impl_trait, "Bar"); } + +#[test] +fn errors_on_unknown_type_in_trait_where_clause() { + let src = r#" + pub trait Foo where T: Unknown {} + + fn main() { + } + "#; + let errors = get_program_errors(src); + assert_eq!(errors.len(), 1); +} + +#[test] +fn does_not_error_if_impl_trait_constraint_is_satisfied_for_concrete_type() { + let src = r#" + pub trait Greeter { + fn greet(self); + } + + pub trait Foo + where + T: Greeter, + { + fn greet(object: U) + where + U: Greeter, + { + object.greet(); + } + } + + pub struct SomeGreeter; + impl Greeter for SomeGreeter { + fn greet(self) {} + } + + pub struct Bar; + + impl Foo for Bar {} + + fn main() {} + "#; + assert_no_errors(src); +} + +#[test] +fn does_not_error_if_impl_trait_constraint_is_satisfied_for_type_variable() { + let src = r#" + pub trait Greeter { + fn greet(self); + } + + pub trait Foo where T: Greeter { + fn greet(object: T) { + object.greet(); + } + } + + pub struct Bar; + + impl Foo for Bar where T: Greeter { + } + + fn main() { + } + "#; + assert_no_errors(src); +} +#[test] +fn errors_if_impl_trait_constraint_is_not_satisfied() { + let src = r#" + pub trait Greeter { + fn greet(self); + } + + pub trait Foo + where + T: Greeter, + { + fn greet(object: U) + where + U: Greeter, + { + object.greet(); + } + } + + pub struct SomeGreeter; + + pub struct Bar; + + impl Foo for Bar {} + + fn main() {} + "#; + let errors = get_program_errors(src); + assert_eq!(errors.len(), 1); + + let CompilationError::ResolverError(ResolverError::TraitNotImplemented { + impl_trait, + missing_trait: the_trait, + type_missing_trait: typ, + .. + }) = &errors[0].0 + else { + panic!("Expected a TraitNotImplemented error, got {:?}", &errors[0].0); + }; + + assert_eq!(the_trait, "Greeter"); + assert_eq!(typ, "SomeGreeter"); + assert_eq!(impl_trait, "Foo"); +} diff --git a/noir/noir-repo/docs/docs/noir/concepts/comptime.md b/noir/noir-repo/docs/docs/noir/concepts/comptime.md index cea3a896c17..37457d47b46 100644 --- a/noir/noir-repo/docs/docs/noir/concepts/comptime.md +++ b/noir/noir-repo/docs/docs/noir/concepts/comptime.md @@ -5,7 +5,7 @@ keywords: [Noir, comptime, compile-time, metaprogramming, macros, quote, unquote sidebar_position: 15 --- -# Overview +## Overview Metaprogramming in Noir is comprised of three parts: 1. `comptime` code @@ -21,7 +21,7 @@ for greater analysis and modification of programs. --- -# Comptime +## Comptime `comptime` is a new keyword in Noir which marks an item as executing or existing at compile-time. It can be used in several ways: @@ -32,11 +32,11 @@ for greater analysis and modification of programs. - `comptime let` to define a variable whose value is evaluated at compile-time. - `comptime for` to run a for loop at compile-time. Syntax sugar for `comptime { for .. }`. -## Scoping +### Scoping Note that while in a `comptime` context, any runtime variables _local to the current function_ are never visible. -## Evaluating +### Evaluating Evaluation rules of `comptime` follows the normal unconstrained evaluation rules for other Noir code. There are a few things to note though: @@ -62,7 +62,7 @@ For example, using globals to generate unique ids should be fine but relying on function itself was called at compile-time previously, it will already be resolved and cannot be modified. To prevent accidentally calling functions you wish to modify at compile-time, it may be helpful to sort your `comptime` annotation functions into a different crate along with any dependencies they require. -## Lowering +### Lowering When a `comptime` value is used in runtime code it must be lowered into a runtime value. This means replacing the expression with the literal that it evaluated to. For example, the code: @@ -102,7 +102,7 @@ comptime fn get_type() -> Type { ... } --- -# (Quasi) Quote +## (Quasi) Quote Macros in Noir are `comptime` functions which return code as a value which is inserted into the call site when it is lowered there. A code value in this case is of type `Quoted` and can be created by a `quote { ... }` expression. @@ -121,7 +121,7 @@ Calling such a function at compile-time without `!` will just return the `Quoted For those familiar with quoting from other languages (primarily lisps), Noir's `quote` is actually a _quasiquote_. This means we can escape the quoting by using the unquote operator to splice values in the middle of quoted code. -# Unquote +## Unquote The unquote operator `$` is usable within a `quote` expression. It takes a variable as an argument, evaluates the variable, and splices the resulting value into the quoted token stream at that point. For example, @@ -160,7 +160,7 @@ comptime { --- -# Annotations +## Annotations Annotations provide a way to run a `comptime` function on an item in the program. When you use an annotation, the function with the same name will be called with that item as an argument: @@ -188,7 +188,7 @@ For example, this is the mechanism used to insert additional trait implementatio #include_code derive-field-count-example noir_stdlib/src/meta/mod.nr rust -## Calling annotations with additional arguments +### Calling annotations with additional arguments Arguments may optionally be given to annotations. When this is done, these additional arguments are passed to the annotation function after the item argument. @@ -201,13 +201,13 @@ We can also take any number of arguments by adding the `varargs` annotation: --- -# Comptime API +## Comptime API Although `comptime`, `quote`, and unquoting provide a flexible base for writing macros, Noir's true metaprogramming ability comes from being able to interact with the compiler through a compile-time API. This API can be accessed through built-in functions in `std::meta` as well as on methods of several `comptime` types. -The following is an incomplete list of some `comptime` types along with some useful methods on them. +The following is an incomplete list of some `comptime` types along with some useful methods on them. You can see more in the standard library [Metaprogramming section](../standard_library/meta). - `Quoted`: A token stream - `Type`: The type of a Noir type @@ -238,7 +238,7 @@ The following is an incomplete list of some `comptime` types along with some use There are many more functions available by exploring the `std::meta` module and its submodules. Using these methods is the key to writing powerful metaprogramming libraries. -## `#[use_callers_scope]` +### `#[use_callers_scope]` Since certain functions such as `Quoted::as_type`, `Expression::as_type`, or `Quoted::as_trait_constraint` will attempt to resolve their contents in a particular scope - it can be useful to change the scope they resolve in. By default @@ -251,7 +251,7 @@ your attribute function and a helper function it calls use it, then they can bot --- -# Example: Derive +## Example: Derive Using all of the above, we can write a `derive` macro that behaves similarly to Rust's but is not built into the language. From the user's perspective it will look like this: diff --git a/noir/noir-repo/docs/docusaurus.config.ts b/noir/noir-repo/docs/docusaurus.config.ts index c7af7e494d1..c53d11e3373 100644 --- a/noir/noir-repo/docs/docusaurus.config.ts +++ b/noir/noir-repo/docs/docusaurus.config.ts @@ -181,37 +181,6 @@ export default { membersWithOwnFile: ['Interface', 'Class', 'TypeAlias', 'Function'], }, ], - [ - 'docusaurus-plugin-typedoc', - { - id: 'noir_js_backend_barretenberg', - entryPoints: ['../tooling/noir_js_backend_barretenberg/src/index.ts'], - tsconfig: '../tooling/noir_js_backend_barretenberg/tsconfig.json', - entryPointStrategy: 'resolve', - out: 'processed-docs/reference/NoirJS/backend_barretenberg', - plugin: ['typedoc-plugin-markdown'], - name: 'backend_barretenberg', - disableSources: true, - excludePrivate: true, - skipErrorChecking: true, - sidebar: { - filteredIds: ['reference/NoirJS/backend_barretenberg/index'], - }, - readme: 'none', - hidePageHeader: true, - hideBreadcrumbs: true, - hideInPageTOC: true, - useCodeBlocks: true, - typeDeclarationFormat: 'table', - propertiesFormat: 'table', - parametersFormat: 'table', - enumMembersFormat: 'table', - indexFormat: 'table', - outputFileStrategy: 'members', - memberPageTitle: '{name}', - membersWithOwnFile: ['Interface', 'Class', 'TypeAlias'], - }, - ], [ 'docusaurus-plugin-typedoc', { diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/how_to/_category_.json b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/how_to/_category_.json index 360a8ad77f0..0b4f367ce53 100644 --- a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/how_to/_category_.json +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/how_to/_category_.json @@ -1,6 +1,5 @@ { - "label": "Modules, Packages and Crates", - "position": 2, + "position": 1, "collapsible": true, "collapsed": true } diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/_category_.json b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/_category_.json index 5b6a20a609a..5d694210bbf 100644 --- a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/_category_.json +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/_category_.json @@ -1,5 +1,5 @@ { - "position": 4, + "position": 0, "collapsible": true, "collapsed": true } diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/cryptographic_primitives/_category_.json b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/cryptographic_primitives/_category_.json index 7da08f8a8c5..5d694210bbf 100644 --- a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/cryptographic_primitives/_category_.json +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/cryptographic_primitives/_category_.json @@ -1,6 +1,5 @@ { - "label": "Concepts", "position": 0, "collapsible": true, "collapsed": true -} \ No newline at end of file +} diff --git a/noir/noir-repo/noir_stdlib/src/hash/mod.nr b/noir/noir-repo/noir_stdlib/src/hash/mod.nr index 15112757312..c5e6da9d76f 100644 --- a/noir/noir-repo/noir_stdlib/src/hash/mod.nr +++ b/noir/noir-repo/noir_stdlib/src/hash/mod.nr @@ -75,6 +75,7 @@ pub fn pedersen_hash_with_separator(input: [Field; N], separator: u3 } #[field(bn254)] +#[inline_always] pub fn derive_generators( domain_separator_bytes: [u8; M], starting_index: u32, diff --git a/noir/noir-repo/noir_stdlib/src/hash/sha256.nr b/noir/noir-repo/noir_stdlib/src/hash/sha256.nr index b5d2624d3e7..a3ac0b9e5da 100644 --- a/noir/noir-repo/noir_stdlib/src/hash/sha256.nr +++ b/noir/noir-repo/noir_stdlib/src/hash/sha256.nr @@ -12,6 +12,20 @@ global MSG_SIZE_PTR = 56; // Size of the message block when packed as 4-byte integer array. global INT_BLOCK_SIZE = 16; +// A `u32` integer consists of 4 bytes. +global INT_SIZE = 4; + +// Index of the integer in the `INT_BLOCK` where the length is written. +global INT_SIZE_PTR = MSG_SIZE_PTR / INT_SIZE; + +// Magic numbers for bit shifting. +// Works with actual bit shifting as well as the compiler turns them into * and / +// but circuit execution appears to be 10% faster this way. +global TWO_POW_8 = 256; +global TWO_POW_16 = TWO_POW_8 * 256; +global TWO_POW_24 = TWO_POW_16 * 256; +global TWO_POW_32 = TWO_POW_24 as u64 * 256; + // Index of a byte in a 64 byte block; ie. 0..=63 type BLOCK_BYTE_PTR = u32; @@ -19,8 +33,8 @@ type BLOCK_BYTE_PTR = u32; type INT_BLOCK = [u32; INT_BLOCK_SIZE]; // A message block is a slice of the original message of a fixed size, -// potentially padded with zeroes. -type MSG_BLOCK = [u8; BLOCK_SIZE]; +// potentially padded with zeros, with neighbouring 4 bytes packed into integers. +type MSG_BLOCK = INT_BLOCK; // The hash is 32 bytes. type HASH = [u8; 32]; @@ -50,16 +64,19 @@ pub fn digest(msg: [u8; N]) -> HASH { pub fn sha256_var(msg: [u8; N], message_size: u64) -> HASH { let message_size = message_size as u32; let num_blocks = N / BLOCK_SIZE; - let mut msg_block: MSG_BLOCK = [0; BLOCK_SIZE]; + let mut msg_block: MSG_BLOCK = [0; INT_BLOCK_SIZE]; + // Intermediate hash, starting with the canonical initial value let mut h: STATE = [ 1779033703, 3144134277, 1013904242, 2773480762, 1359893119, 2600822924, 528734635, 1541459225, - ]; // Intermediate hash, starting with the canonical initial value - let mut msg_byte_ptr = 0; // Pointer into msg_block + ]; + // Pointer into msg_block on a 64 byte scale + let mut msg_byte_ptr = 0; for i in 0..num_blocks { let msg_start = BLOCK_SIZE * i; let (new_msg_block, new_msg_byte_ptr) = unsafe { build_msg_block(msg, message_size, msg_start) }; + if msg_start < message_size { msg_block = new_msg_block; } @@ -77,7 +94,7 @@ pub fn sha256_var(msg: [u8; N], message_size: u64) -> HASH { // If the block is filled, compress it. // An un-filled block is handled after this loop. if (msg_start < message_size) & (msg_byte_ptr == BLOCK_SIZE) { - h = sha256_compression(msg_u8_to_u32(msg_block), h); + h = sha256_compression(msg_block, h); } } @@ -114,49 +131,39 @@ pub fn sha256_var(msg: [u8; N], message_size: u64) -> HASH { // Pad the rest such that we have a [u32; 2] block at the end representing the length // of the message, and a block of 1 0 ... 0 following the message (i.e. [1 << 7, 0, ..., 0]). // Here we rely on the fact that everything beyond the available input is set to 0. - msg_block[msg_byte_ptr] = 1 << 7; - let last_block = msg_block; + msg_block = update_block_item( + msg_block, + msg_byte_ptr, + |msg_item| set_item_byte_then_zeros(msg_item, msg_byte_ptr, 1 << 7), + ); msg_byte_ptr = msg_byte_ptr + 1; + let last_block = msg_block; // If we don't have room to write the size, compress the block and reset it. if msg_byte_ptr > MSG_SIZE_PTR { - h = sha256_compression(msg_u8_to_u32(msg_block), h); + h = sha256_compression(msg_block, h); // `attach_len_to_msg_block` will zero out everything after the `msg_byte_ptr`. msg_byte_ptr = 0; } msg_block = unsafe { attach_len_to_msg_block(msg_block, msg_byte_ptr, message_size) }; - if !crate::runtime::is_unconstrained() { + if !is_unconstrained() { verify_msg_len(msg_block, last_block, msg_byte_ptr, message_size); } hash_final_block(msg_block, h) } -// Convert 64-byte array to array of 16 u32s -fn msg_u8_to_u32(msg: MSG_BLOCK) -> INT_BLOCK { - let mut msg32: INT_BLOCK = [0; INT_BLOCK_SIZE]; - - for i in 0..INT_BLOCK_SIZE { - let mut msg_field: Field = 0; - for j in 0..4 { - msg_field = msg_field * 256 + msg[64 - 4 * (i + 1) + j] as Field; - } - msg32[15 - i] = msg_field as u32; - } - - msg32 -} - // Take `BLOCK_SIZE` number of bytes from `msg` starting at `msg_start`. -// Returns the block and the length that has been copied rather than padded with zeroes. +// Returns the block and the length that has been copied rather than padded with zeros. unconstrained fn build_msg_block( msg: [u8; N], message_size: u32, msg_start: u32, ) -> (MSG_BLOCK, BLOCK_BYTE_PTR) { - let mut msg_block: MSG_BLOCK = [0; BLOCK_SIZE]; + let mut msg_block: MSG_BLOCK = [0; INT_BLOCK_SIZE]; + // We insert `BLOCK_SIZE` bytes (or up to the end of the message) let block_input = if msg_start + BLOCK_SIZE > message_size { if message_size < msg_start { @@ -169,29 +176,73 @@ unconstrained fn build_msg_block( } else { BLOCK_SIZE }; - for k in 0..block_input { - msg_block[k] = msg[msg_start + k]; + + // Figure out the number of items in the int array that we have to pack. + // e.g. if the input is [0,1,2,3,4,5] then we need to pack it as 2 items: [0123, 4500] + let mut int_input = block_input / INT_SIZE; + if block_input % INT_SIZE != 0 { + int_input = int_input + 1; + }; + + for i in 0..int_input { + let mut msg_item: u32 = 0; + // Always construct the integer as 4 bytes, even if it means going beyond the input. + for j in 0..INT_SIZE { + let k = i * INT_SIZE + j; + let msg_byte = if k < block_input { + msg[msg_start + k] + } else { + 0 + }; + msg_item = lshift8(msg_item, 1) + msg_byte as u32; + } + msg_block[i] = msg_item; } + + // Returning the index as if it was a 64 byte array. + // We have to project it down to 16 items and bit shifting to get a byte back if we need it. (msg_block, block_input) } // Verify the block we are compressing was appropriately constructed by `build_msg_block` // and matches the input data. Returns the index of the first unset item. +// If `message_size` is less than `msg_start` then this is called with the old non-empty block; +// in that case we can skip verification, ie. no need to check that everything is zero. fn verify_msg_block( msg: [u8; N], message_size: u32, msg_block: MSG_BLOCK, msg_start: u32, ) -> BLOCK_BYTE_PTR { - let mut msg_byte_ptr: u32 = 0; // Message byte pointer + let mut msg_byte_ptr = 0; let mut msg_end = msg_start + BLOCK_SIZE; if msg_end > N { msg_end = N; } + // We might have to go beyond the input to pad the fields. + if msg_end % INT_SIZE != 0 { + msg_end = msg_end + INT_SIZE - msg_end % INT_SIZE; + } - for k in msg_start..msg_end { - if k < message_size { - assert_eq(msg_block[msg_byte_ptr], msg[k]); + // Reconstructed packed item. + let mut msg_item: u32 = 0; + + // Inclusive at the end so that we can compare the last item. + let mut i: u32 = 0; + for k in msg_start..=msg_end { + if k % INT_SIZE == 0 { + // If we consumed some input we can compare against the block. + if (msg_start < message_size) & (k > msg_start) { + assert_eq(msg_block[i], msg_item as u32); + i = i + 1; + msg_item = 0; + } + } + // Shift the accumulator + msg_item = lshift8(msg_item, 1); + // If we have input to consume, add it at the rightmost position. + if k < message_size & k < msg_end { + msg_item = msg_item + msg[k] as u32; msg_byte_ptr = msg_byte_ptr + 1; } } @@ -199,69 +250,261 @@ fn verify_msg_block( msg_byte_ptr } -// Verify the block we are compressing was appropriately padded with zeroes by `build_msg_block`. +// Verify the block we are compressing was appropriately padded with zeros by `build_msg_block`. // This is only relevant for the last, potentially partially filled block. fn verify_msg_block_padding(msg_block: MSG_BLOCK, msg_byte_ptr: BLOCK_BYTE_PTR) { + // Check all the way to the end of the block. + verify_msg_block_zeros(msg_block, msg_byte_ptr, INT_BLOCK_SIZE); +} + +// Verify that a region of ints in the message block are (partially) zeroed, +// up to an (exclusive) maximum which can either be the end of the block +// or just where the size is to be written. +fn verify_msg_block_zeros( + msg_block: MSG_BLOCK, + mut msg_byte_ptr: BLOCK_BYTE_PTR, + max_int_byte_ptr: u32, +) { // This variable is used to get around the compiler under-constrained check giving a warning. // We want to check against a constant zero, but if it does not come from the circuit inputs // or return values the compiler check will issue a warning. let zero = msg_block[0] - msg_block[0]; - for i in 0..BLOCK_SIZE { - if i >= msg_byte_ptr { + // First integer which is supposed to be (partially) zero. + let mut int_byte_ptr = msg_byte_ptr / INT_SIZE; + + // Check partial zeros. + let modulo = msg_byte_ptr % INT_SIZE; + if modulo != 0 { + let zeros = INT_SIZE - modulo; + let mask = if zeros == 3 { + TWO_POW_24 + } else if zeros == 2 { + TWO_POW_16 + } else { + TWO_POW_8 + }; + assert_eq(msg_block[int_byte_ptr] % mask, zero); + int_byte_ptr = int_byte_ptr + 1; + } + + // Check the rest of the items. + for i in 0..max_int_byte_ptr { + if i >= int_byte_ptr { assert_eq(msg_block[i], zero); } } } +// Verify that up to the byte pointer the two blocks are equal. +// At the byte pointer the new block can be partially zeroed. +fn verify_msg_block_equals_last( + msg_block: MSG_BLOCK, + last_block: MSG_BLOCK, + mut msg_byte_ptr: BLOCK_BYTE_PTR, +) { + // msg_byte_ptr is the position at which they are no longer have to be the same. + // First integer which is supposed to be (partially) zero contains that pointer. + let mut int_byte_ptr = msg_byte_ptr / INT_SIZE; + + // Check partial zeros. + let modulo = msg_byte_ptr % INT_SIZE; + if modulo != 0 { + // Reconstruct the partially zero item from the last block. + let last_field = last_block[int_byte_ptr]; + let mut msg_item: u32 = 0; + // Reset to where they are still equal. + msg_byte_ptr = msg_byte_ptr - modulo; + for i in 0..INT_SIZE { + msg_item = lshift8(msg_item, 1); + if i < modulo { + msg_item = msg_item + get_item_byte(last_field, msg_byte_ptr) as u32; + msg_byte_ptr = msg_byte_ptr + 1; + } + } + assert_eq(msg_block[int_byte_ptr], msg_item); + } + + for i in 0..INT_SIZE_PTR { + if i < int_byte_ptr { + assert_eq(msg_block[i], last_block[i]); + } + } +} + +// Apply a function on the block item which the pointer indicates. +fn update_block_item( + mut msg_block: MSG_BLOCK, + msg_byte_ptr: BLOCK_BYTE_PTR, + f: fn[Env](u32) -> u32, +) -> MSG_BLOCK { + let i = msg_byte_ptr / INT_SIZE; + msg_block[i] = f(msg_block[i]); + msg_block +} + +// Set the rightmost `zeros` number of bytes to 0. +fn set_item_zeros(item: u32, zeros: u8) -> u32 { + lshift8(rshift8(item, zeros), zeros) +} + +// Replace one byte in the item with a value, and set everything after it to zero. +fn set_item_byte_then_zeros(msg_item: u32, msg_byte_ptr: BLOCK_BYTE_PTR, msg_byte: u8) -> u32 { + let zeros = INT_SIZE - msg_byte_ptr % INT_SIZE; + let zeroed_item = set_item_zeros(msg_item, zeros as u8); + let new_item = byte_into_item(msg_byte, msg_byte_ptr); + zeroed_item + new_item +} + +// Get a byte of a message item according to its overall position in the `BLOCK_SIZE` space. +fn get_item_byte(mut msg_item: u32, msg_byte_ptr: BLOCK_BYTE_PTR) -> u8 { + // How many times do we have to shift to the right to get to the position we want? + let max_shifts = INT_SIZE - 1; + let shifts = max_shifts - msg_byte_ptr % INT_SIZE; + msg_item = rshift8(msg_item, shifts as u8); + // At this point the byte we want is in the rightmost position. + msg_item as u8 +} + +// Project a byte into a position in a field based on the overall block pointer. +// For example putting 1 into pointer 5 would be 100, because overall we would +// have [____, 0100] with indexes [0123,4567]. +fn byte_into_item(msg_byte: u8, msg_byte_ptr: BLOCK_BYTE_PTR) -> u32 { + let mut msg_item = msg_byte as u32; + // How many times do we have to shift to the left to get to the position we want? + let max_shifts = INT_SIZE - 1; + let shifts = max_shifts - msg_byte_ptr % INT_SIZE; + lshift8(msg_item, shifts as u8) +} + +// Construct a field out of 4 bytes. +fn make_item(b0: u8, b1: u8, b2: u8, b3: u8) -> u32 { + let mut item = b0 as u32; + item = lshift8(item, 1) + b1 as u32; + item = lshift8(item, 1) + b2 as u32; + item = lshift8(item, 1) + b3 as u32; + item +} + +// Shift by 8 bits to the left between 0 and 4 times. +// Checks `is_unconstrained()` to just use a bitshift if we're running in an unconstrained context, +// otherwise multiplies by 256. +fn lshift8(item: u32, shifts: u8) -> u32 { + if is_unconstrained() { + if item == 0 { + 0 + } else { + // Brillig wouldn't shift 0<<4 without overflow. + item << (8 * shifts) + } + } else { + // We can do a for loop up to INT_SIZE or an if-else. + if shifts == 0 { + item + } else if shifts == 1 { + item * TWO_POW_8 + } else if shifts == 2 { + item * TWO_POW_16 + } else if shifts == 3 { + item * TWO_POW_24 + } else { + // Doesn't make sense, but it's most likely called on 0 anyway. + 0 + } + } +} + +// Shift by 8 bits to the right between 0 and 4 times. +// Checks `is_unconstrained()` to just use a bitshift if we're running in an unconstrained context, +// otherwise divides by 256. +fn rshift8(item: u32, shifts: u8) -> u32 { + if is_unconstrained() { + item >> (8 * shifts) + } else { + // Division wouldn't work on `Field`. + if shifts == 0 { + item + } else if shifts == 1 { + item / TWO_POW_8 + } else if shifts == 2 { + item / TWO_POW_16 + } else if shifts == 3 { + item / TWO_POW_24 + } else { + 0 + } + } +} + // Zero out all bytes between the end of the message and where the length is appended, // then write the length into the last 8 bytes of the block. unconstrained fn attach_len_to_msg_block( mut msg_block: MSG_BLOCK, - msg_byte_ptr: BLOCK_BYTE_PTR, + mut msg_byte_ptr: BLOCK_BYTE_PTR, message_size: u32, ) -> MSG_BLOCK { // We assume that `msg_byte_ptr` is less than 57 because if not then it is reset to zero before calling this function. - // In any case, fill blocks up with zeros until the last 64 (i.e. until msg_byte_ptr = 56). - for i in msg_byte_ptr..MSG_SIZE_PTR { + // In any case, fill blocks up with zeros until the last 64 bits (i.e. until msg_byte_ptr = 56). + // There can be one item which has to be partially zeroed. + let modulo = msg_byte_ptr % INT_SIZE; + if modulo != 0 { + // Index of the block in which we find the item we need to partially zero. + let i = msg_byte_ptr / INT_SIZE; + let zeros = INT_SIZE - modulo; + msg_block[i] = set_item_zeros(msg_block[i], zeros as u8); + msg_byte_ptr = msg_byte_ptr + zeros; + } + + // The rest can be zeroed without bit shifting anything. + for i in (msg_byte_ptr / INT_SIZE)..INT_SIZE_PTR { msg_block[i] = 0; } + // Set the last two 4 byte ints as the first/second half of the 8 bytes of the length. let len = 8 * message_size; let len_bytes: [u8; 8] = (len as Field).to_be_bytes(); - for i in 0..8 { - msg_block[MSG_SIZE_PTR + i] = len_bytes[i]; + for i in 0..=1 { + let shift = i * 4; + msg_block[INT_SIZE_PTR + i] = make_item( + len_bytes[shift], + len_bytes[shift + 1], + len_bytes[shift + 2], + len_bytes[shift + 3], + ); } msg_block } -// Verify that the message length was correctly written by `attach_len_to_msg_block`. +// Verify that the message length was correctly written by `attach_len_to_msg_block`, +// and that everything between the byte pointer and the size pointer was zeroed, +// and that everything before the byte pointer was untouched. fn verify_msg_len( msg_block: MSG_BLOCK, last_block: MSG_BLOCK, msg_byte_ptr: BLOCK_BYTE_PTR, message_size: u32, ) { - for i in 0..MSG_SIZE_PTR { - let predicate = (i < msg_byte_ptr) as u8; - let expected_byte = predicate * last_block[i]; - assert_eq(msg_block[i], expected_byte); - } + // Check zeros up to the size pointer. + verify_msg_block_zeros(msg_block, msg_byte_ptr, INT_SIZE_PTR); + + // Check that up to the pointer we match the last block. + verify_msg_block_equals_last(msg_block, last_block, msg_byte_ptr); // We verify the message length was inserted correctly by reversing the byte decomposition. - let len = 8 * message_size; - let mut reconstructed_len: Field = 0; - for i in MSG_SIZE_PTR..BLOCK_SIZE { - reconstructed_len = 256 * reconstructed_len + msg_block[i] as Field; + let mut reconstructed_len: u64 = 0; + for i in INT_SIZE_PTR..INT_BLOCK_SIZE { + reconstructed_len = reconstructed_len * TWO_POW_32; + reconstructed_len = reconstructed_len + msg_block[i] as u64; } - assert_eq(reconstructed_len, len as Field); + let len = 8 * message_size as u64; + assert_eq(reconstructed_len, len); } // Perform the final compression, then transform the `STATE` into `HASH`. fn hash_final_block(msg_block: MSG_BLOCK, mut state: STATE) -> HASH { let mut out_h: HASH = [0; 32]; // Digest as sequence of bytes // Hash final padded block - state = sha256_compression(msg_u8_to_u32(msg_block), state); + state = sha256_compression(msg_block, state); // Return final hash as byte array for j in 0..8 { @@ -275,6 +518,11 @@ fn hash_final_block(msg_block: MSG_BLOCK, mut state: STATE) -> HASH { } mod tests { + use super::{ + attach_len_to_msg_block, build_msg_block, byte_into_item, get_item_byte, lshift8, make_item, + set_item_byte_then_zeros, set_item_zeros, + }; + use super::{INT_BLOCK, INT_BLOCK_SIZE, MSG_BLOCK}; use super::sha256_var; #[test] @@ -510,4 +758,79 @@ mod tests { assert_eq(var_length_hash_575, fixed_length_hash); assert_eq(var_length_hash_576, fixed_length_hash); } + + #[test] + fn test_get_item_byte() { + let fld = make_item(10, 20, 30, 40); + assert_eq(fld, 0x0a141e28); + assert_eq(get_item_byte(fld, 0), 10); + assert_eq(get_item_byte(fld, 4), 10); + assert_eq(get_item_byte(fld, 6), 30); + } + + #[test] + fn test_byte_into_item() { + let fld = make_item(0, 20, 0, 0); + assert_eq(byte_into_item(20, 1), fld); + assert_eq(byte_into_item(20, 5), fld); + } + + #[test] + fn test_set_item_zeros() { + let fld0 = make_item(10, 20, 30, 40); + let fld1 = make_item(10, 0, 0, 0); + assert_eq(set_item_zeros(fld0, 3), fld1); + assert_eq(set_item_zeros(fld0, 4), 0); + assert_eq(set_item_zeros(0, 4), 0); + } + + #[test] + fn test_set_item_byte_then_zeros() { + let fld0 = make_item(10, 20, 30, 40); + let fld1 = make_item(10, 50, 0, 0); + assert_eq(set_item_byte_then_zeros(fld0, 1, 50), fld1); + } + + #[test] + fn test_build_msg_block_start_0() { + let input = [ + 102, 114, 111, 109, 58, 114, 117, 110, 110, 105, 101, 114, 46, 108, 101, 97, 103, 117, + 101, 115, 46, 48, + ]; + assert_eq(input.len(), 22); + let (msg_block, msg_byte_ptr) = unsafe { build_msg_block(input, input.len(), 0) }; + assert_eq(msg_byte_ptr, input.len()); + assert_eq(msg_block[0], make_item(input[0], input[1], input[2], input[3])); + assert_eq(msg_block[1], make_item(input[4], input[5], input[6], input[7])); + assert_eq(msg_block[5], make_item(input[20], input[21], 0, 0)); + assert_eq(msg_block[6], 0); + } + + #[test] + fn test_build_msg_block_start_1() { + let input = [ + 102, 114, 111, 109, 58, 114, 117, 110, 110, 105, 101, 114, 46, 108, 101, 97, 103, 117, + 101, 115, 46, 48, 106, 64, 105, 99, 108, 111, 117, 100, 46, 99, 111, 109, 13, 10, 99, + 111, 110, 116, 101, 110, 116, 45, 116, 121, 112, 101, 58, 116, 101, 120, 116, 47, 112, + 108, 97, 105, 110, 59, 32, 99, 104, 97, 114, 115, 101, 116, + ]; + assert_eq(input.len(), 68); + let (msg_block, msg_byte_ptr) = unsafe { build_msg_block(input, input.len(), 64) }; + assert_eq(msg_byte_ptr, 4); + assert_eq(msg_block[0], make_item(input[64], input[65], input[66], input[67])); + assert_eq(msg_block[1], 0); + } + + #[test] + fn test_attach_len_to_msg_block() { + let input: INT_BLOCK = [ + 2152555847, 1397309779, 1936618851, 1262052426, 1936876331, 1985297723, 543702374, + 1919905082, 1131376244, 1701737517, 1417244773, 978151789, 1697470053, 1920166255, + 1849316213, 1651139939, + ]; + let msg_block = unsafe { attach_len_to_msg_block(input, 1, 448) }; + assert_eq(msg_block[0], ((1 << 7) as u32) * 256 * 256 * 256); + assert_eq(msg_block[1], 0); + assert_eq(msg_block[15], 3584); + } } diff --git a/noir/noir-repo/scripts/bump-bb.sh b/noir/noir-repo/scripts/bump-bb.sh index fb1a2b1d31e..661a8eb9d43 100755 --- a/noir/noir-repo/scripts/bump-bb.sh +++ b/noir/noir-repo/scripts/bump-bb.sh @@ -5,7 +5,7 @@ BB_VERSION=$1 sed -i.bak "s/^VERSION=.*/VERSION=\"$BB_VERSION\"/" ./scripts/install_bb.sh && rm ./scripts/install_bb.sh.bak tmp=$(mktemp) -INTEGRATION_TESTS_PACKAGE_JSON=./compiler/integration_tests/package.json +INTEGRATION_TESTS_PACKAGE_JSON=./compiler/integration-tests/package.json jq --arg v $BB_VERSION '.dependencies."@aztec/bb.js" = $v' $INTEGRATION_TESTS_PACKAGE_JSON > $tmp && mv $tmp $INTEGRATION_TESTS_PACKAGE_JSON YARN_ENABLE_IMMUTABLE_INSTALLS=false yarn install diff --git a/noir/noir-repo/scripts/install_bb.sh b/noir/noir-repo/scripts/install_bb.sh index 596f0a54ba4..64baf78c182 100755 --- a/noir/noir-repo/scripts/install_bb.sh +++ b/noir/noir-repo/scripts/install_bb.sh @@ -1,6 +1,6 @@ #!/bin/bash -VERSION="0.58.0" +VERSION="0.60.0" BBUP_PATH=~/.bb/bbup diff --git a/noir/noir-repo/test_programs/compile_success_empty/arithmetic_generics/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/arithmetic_generics/src/main.nr index f599d2879ee..ae50748c8e7 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/arithmetic_generics/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/arithmetic_generics/src/main.nr @@ -77,25 +77,25 @@ fn equiv_trans( x: Equiv, y: Equiv, ) -> Equiv, Equiv), V, (Equiv, Equiv)> { - Equiv { to_: |z| { y.to(x.to(z)) }, fro_: |z| { x.fro(y.fro(z)) } } + Equiv { to_: |z| y.to(x.to(z)), fro_: |z| x.fro(y.fro(z)) } } fn mul_one_r() -> Equiv, (), W, ()> { - Equiv { to_: |_x| { W {} }, fro_: |_x| { W {} } } + Equiv { to_: |_x| W {}, fro_: |_x| W {} } } fn add_equiv_r( _: Equiv, EN, W, EM>, ) -> Equiv, (), W, ()> { - Equiv { to_: |_x| { W {} }, fro_: |_x| { W {} } } + Equiv { to_: |_x| W {}, fro_: |_x| W {} } } fn mul_comm() -> Equiv, (), W, ()> { - Equiv { to_: |_x| { W {} }, fro_: |_x| { W {} } } + Equiv { to_: |_x| W {}, fro_: |_x| W {} } } fn mul_add() -> Equiv, (), W, ()> { - Equiv { to_: |_x| { W {} }, fro_: |_x| { W {} } } + Equiv { to_: |_x| W {}, fro_: |_x| W {} } } // (N + 1) * N == N * N + N diff --git a/noir/noir-repo/test_programs/compile_success_empty/comptime_closures/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/comptime_closures/src/main.nr index 132c6df6c91..e8a0366a304 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/comptime_closures/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/comptime_closures/src/main.nr @@ -6,7 +6,7 @@ fn main() { fn closure_test(mut x: Field) { let one = 1; - let add1 = |z| { (|| { *z += one; })() }; + let add1 = |z| (|| { *z += one; })(); let two = 2; let add2 = |z| { *z = *z + two; }; diff --git a/noir/noir-repo/test_programs/compile_success_empty/inner_outer_cl/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/inner_outer_cl/src/main.nr index 57890cd6b67..17cbabec48e 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/inner_outer_cl/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/inner_outer_cl/src/main.nr @@ -2,7 +2,7 @@ fn main() { let z1 = 0; let z2 = 1; let cl_outer = |x| { - let cl_inner = |y| { x + y + z2 }; + let cl_inner = |y| x + y + z2; cl_inner(1) + z1 }; let result = cl_outer(1); diff --git a/noir/noir-repo/test_programs/compile_success_empty/use_callers_scope/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/use_callers_scope/src/main.nr index bc93bc5187e..26429997f0e 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/use_callers_scope/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/use_callers_scope/src/main.nr @@ -19,7 +19,7 @@ mod bar { // Ensure closures can still access Bar even // though `map` separates them from `fn_attr`. - let _ = &[1, 2, 3].map(|_| { quote { Bar }.as_type() }); + let _ = &[1, 2, 3].map(|_| quote { Bar }.as_type()); } // use_callers_scope should also work nested diff --git a/noir/noir-repo/test_programs/execution_success/double_verify_honk_proof/Nargo.toml b/noir/noir-repo/test_programs/execution_success/double_verify_honk_proof/Nargo.toml deleted file mode 100644 index 5f819990c72..00000000000 --- a/noir/noir-repo/test_programs/execution_success/double_verify_honk_proof/Nargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "double_verify_honk_proof" -type = "bin" -authors = [""] - -[dependencies] diff --git a/noir/noir-repo/test_programs/execution_success/double_verify_honk_proof/Prover.toml b/noir/noir-repo/test_programs/execution_success/double_verify_honk_proof/Prover.toml deleted file mode 100644 index f8e7ba41a18..00000000000 --- a/noir/noir-repo/test_programs/execution_success/double_verify_honk_proof/Prover.toml +++ /dev/null @@ -1,5 +0,0 @@ -key_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" -proof = ["0x0000000000000000000000000000000000000000000000000000000000000040", "0x0000000000000000000000000000000000000000000000000000000000000011", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000042ab5d6d1986846cf", "0x00000000000000000000000000000000000000000000000b75c020998797da78", "0x0000000000000000000000000000000000000000000000005a107acb64952eca", "0x000000000000000000000000000000000000000000000000000031e97a575e9d", "0x00000000000000000000000000000000000000000000000b5666547acf8bd5a4", "0x00000000000000000000000000000000000000000000000c410db10a01750aeb", "0x00000000000000000000000000000000000000000000000d722669117f9758a4", "0x000000000000000000000000000000000000000000000000000178cbf4206471", "0x000000000000000000000000000000000000000000000000e91b8a11e7842c38", "0x000000000000000000000000000000000000000000000007fd51009034b3357f", "0x000000000000000000000000000000000000000000000009889939f81e9c7402", "0x0000000000000000000000000000000000000000000000000000f94656a2ca48", "0x000000000000000000000000000000000000000000000006fb128b46c1ddb67f", "0x0000000000000000000000000000000000000000000000093fe27776f50224bd", "0x000000000000000000000000000000000000000000000004a0c80c0da527a081", "0x0000000000000000000000000000000000000000000000000001b52c2020d746", "0x0000000000000000000000000000005a9bae947e1e91af9e4033d8d6aa6ed632", "0x000000000000000000000000000000000025e485e013446d4ac7981c88ba6ecc", "0x000000000000000000000000000000ff1e0496e30ab24a63b32b2d1120b76e62", "0x00000000000000000000000000000000001afe0a8a685d7cd85d1010e55d9d7c", "0x000000000000000000000000000000b0804efd6573805f991458295f510a2004", "0x00000000000000000000000000000000000c81a178016e2fe18605022d5a8b0e", "0x000000000000000000000000000000eba51e76eb1cfff60a53a0092a3c3dea47", "0x000000000000000000000000000000000022e7466247b533282f5936ac4e6c15", "0x00000000000000000000000000000071b1d76edf770edff98f00ff4deec264cd", "0x00000000000000000000000000000000001e48128e68794d8861fcbb2986a383", "0x000000000000000000000000000000d3a2af4915ae6d86b097adc377fafda2d4", "0x000000000000000000000000000000000006359de9ca452dab3a4f1f8d9c9d98", "0x0000000000000000000000000000006cf7dd96d7636fda5953191b1ad776d491", "0x00000000000000000000000000000000001633d881a08d136e834cb13a28fcc6", "0x00000000000000000000000000000001254956cff6908b069fca0e6cf1c47eb1", "0x000000000000000000000000000000000006f4d4dd3890e997e75e75886bf8f7", "0x0000000000000000000000000000006cf7dd96d7636fda5953191b1ad776d491", "0x00000000000000000000000000000000001633d881a08d136e834cb13a28fcc6", "0x00000000000000000000000000000001254956cff6908b069fca0e6cf1c47eb1", "0x000000000000000000000000000000000006f4d4dd3890e997e75e75886bf8f7", "0x000000000000000000000000000000f968b227a358a305607f3efc933823d288", "0x00000000000000000000000000000000000eaf8adb390375a76d95e918b65e08", "0x000000000000000000000000000000bb34b4b447aae56f5e24f81c3acd6d547f", "0x00000000000000000000000000000000002175d012746260ebcfe339a91a81e1", "0x00000000000000000000000000000052eebbd1f6f7554e837f60c44000ed14b6", "0x00000000000000000000000000000000001c1c045a3ec94b8801f2272cc0b3f4", "0x0000000000000000000000000000004d2ef74134578f6b431a9df071ffca4292", "0x0000000000000000000000000000000000291326ade7aa6f0dfc8900eab5580b", "0x0000000000000000000000000000002433eec6418a6dba820c9527e2581fc8bc", "0x00000000000000000000000000000000000e88b7daad19af2ac2f9bdf9e50ee2", "0x000000000000000000000000000000dcfce2c427155cc3e4d035735d3dd5ece8", "0x00000000000000000000000000000000002d7d473cac1a15d0fee8b22c1a7b3e", "0x1a4249b90be4602c8ff40c7c276160ee41b2a0f8a238ce7706e9face2db03d48", "0x162204b9d54d3ffd285c393a5a1ff76ee681474fd780a21a3cf7fac5c24fc2b9", "0x30279eb953d8ee79b2155c69c04e6443c5de6bf7e02886256dd7b3cd3c9502a4", "0x0d32c1bd21baf43e72d5d82d461ef54833807ff81a877adc822f27a6db88d754", "0x0fe15e055c0803d5ebe6dd77689b70cfd82138f008810ce24535c992daaff27d", "0x1fba82c012671212ce2fc13fd09bf8fba4f7d5875ab8d37495d1ccfcff287331", "0x090738a5842fa4d2699b3726aa0dd97cb59569b4be2c6825335ec4969f859dc2", "0x0c6cb72dabbc28abcf4a50c203534e066c29f48c24ca64d672092f263df3f9d7", "0x0f27fbea0d9145f815c288b50fe7e8c10b8185d325b5264624fd57102855d05d", "0x2a815cd3fd1c43c72ee0130465250ff771d1e7be2347e4ada331b83265a03450", "0x148b4ecf2ad7ed17409417086867ee27bc1b0906dbc9cbb3714c285071e2db70", "0x08e700a42b1d6d36ee65f8ebedf47d3a44463ff9fa579dce13b7492e20142c3a", "0x2e23c69521d572ff2152c50f8c9a9191535f4cf37f95f1e0428692e78842b642", "0x14519e0354365923fb41400c19866135b45e975d56a0980260bc99f0390b1d5f", "0x04caded1f05738f736cb5bcf08d785e395e58eb7738523a20638aa16bc51593e", "0x28787eaccd38383215ea21ec02895c32d979f68ca155f534a2e2d377bff6698b", "0x20a1b81fa96c58cf11c5762c5ceb731efdcb081fca2d34d5c463d2cf40e6da18", "0x11789a06fe3bf53833741d180f068d29534d5bb58a5c64b8119542e62b189fb4", "0x23d00fcd032ace719ffcbc513bfa177a55b04377d76455c2788d999d05d011e2", "0x01f0e81b57b4a73cc118e51ede18f8724debf25c2d109db6ef45280f99f1a3fa", "0x156d1c9b61749810de728f259c2c1c1fd4dbff97101426e26087ca461c93307c", "0x1c5d619ac3a478cfd06d5eebfd879960bb321236be173813f5e78d1366d32c69", "0x250cfae4e1dfc551406f1f3d10b649a637dcb7bcb0f6f697994cf96afd35d0c1", "0x242b999f58cf5f53c874d1092bd38725aa9ea076f5bc8f176efa9ea23393874b", "0x2e15748255c4a5e0e9fe38047341b692a967257de27a85a3a38681bc9f1602ea", "0x01ef83886ea7017253699cb6371988eb8e21b4f7023d7479ece4907fe6d4a6fd", "0x08db2dbc271e375b9312f695c59c48f313235b3432cad50921c8d9ad6dd7ad7a", "0x199309f2c2cd45c15a4abb0e6554a1615ff5a6e9488a8d900bbf835fc8f664ef", "0x074be7a3d88e31ab1b59c9208c012bcfb1f85f351c709e68134996891db52b57", "0x301b1011354d2ebf46134fc4d6d734bb6ed8542d719f38f5e09a376a580cad7f", "0x12968f3eccaa27e44f14d5aaac6ecb70c00d040e07536292e685d7cab03fc563", "0x2110a023c8c22fd2ed70270a2d0a265b92a32ce2217ffe1be9a5d7d5c25f512f", "0x1e8cf4c60c53900f0430d5b44de5804fe8b38299bc803beeb4216e1a289cf624", "0x12301cb908ccb28a2616e29b831ec7105b5d3ebf45ff5fe91d50a9dd53a50b52", "0x0f1029ed107d84ff2d6d4a416cbd01da3f3d7bf5b2209ce93ba424f4b85616fc", "0x1b431d016611b8abd684afd9e92331c3325967b1116bfa91d4f44e2f8e2c9fc2", "0x281e335a0fd117064c8ace3f01e02b134a19e9b9220571ebfaaaa0e3a12d34db", "0x22559c106f77e2ae95677d5e38e288343e3b7168371aec7d3aaab9ef8150af70", "0x13f113b1d9b590149cf08c3f6e90589cda5c7b98528866b891256cb9d5d814e7", "0x10252ef388e4c80246962e98b9e976fab2cd25e1e6f1e3fd2a7d4786c5218a97", "0x16b890723dfdebd9912a9207255f95cb800222165b6fae97ec46e461f23e83f3", "0x25caf77c7d2e8e069341ec90f3c8f6d64319cfd2d77cab0625cf0377285ba11c", "0x016c84288b0bc3c50eebbe250cdd5a4ee50b2c65a24ac64d0c930cbdecb95141", "0x20a537c045b069d47dc6315f45b391f60681222381e5059ec7c8b17bf677d911", "0x2594c0edfcd4064d215a3d797bc8e3b2f401c61f3961ae96ccbec8f8fd29e81f", "0x1c831d7047483ca00ed59bdb84c47ffb8bbebbae92aa164c7b35fcffbb8a35d3", "0x2ea7f60de52b8cd6b0bd06f861fc1f2c5ed1d1fbfa53caccdb836400a03df434", "0x275c6c8bd115f7d2ce196439e2330fad305c6745bab0bf1ce3f2fa32dadc3c43", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x2b3f4e210619347288731e7f0eea1ae60dd8696fe87319044864d099a03a9536", "0x0fecd3d2aebedeb8be2b0b7e3a74de9ec8bd2cb72851541463729e0715aef48b", "0x10bee385ad0c2cd3ff88ef4d630840749e4367f9add4a300fc4f545a7778e92c", "0x1fe792730eeafbd22c4eb80e86e2b40108b1e55b2a08db786289eea5745b9e3b", "0x04d411679da432816b213cd5580dda1fd6c2f258684c036be19b5b26baca583c", "0x159f17b655d2b8a803e0cfb564918628be52d3baa950ca1b127854491624f8f4", "0x225340463867d9252a1269013536e2e1dd219aa18eadef13c324b63d44679334", "0x1885e231554e02abb40ed54b72ebf09b883d0298a6bc06fc645a30365f370ef2", "0x233344517f25170972b8ba35d01f2df2e073d322993abce7df26796126e93498", "0x08990e8faa13b18b4433ec417c5cc596885e11ffd372d5f612c08cc79a5d5c80", "0x1e960a0c892b755c28e21dcbed816c1b182d7da43bae07f8ee622bd4485f79e7", "0x27b58e2ee290a179d349ace82752528b2ff946d60c092b99ef42f53c25d0c99f", "0x2a5cf8a3193107d982edd253002c7a52ab876b445dde8307ab78fbdca022d93c", "0x2b1ab4d5277f8c82750c1c7bd043889b71465ec64a9afc1bfa37d06b1ebd0725", "0x2a0dbf5c4373a58a83d5f2a031ea0615bf12800e33b70c3191a7cbb15966ced8", "0x1f272bb4a19d14a0abdfebc9fc83125e10623b9aef730f8d25f2bf5bead38ea9", "0x2c2339cf0ae7aff56091a568c1e2c3f01f52d8ed13400737fd31eaabcaffb9bd", "0x21f5fefe6b5fa0b5da71089befb74a1a39e52b4f830cb330c3c284e154614dfd", "0x1e6f6ba4b2444586b380dc4e2b3fad111ff1f4754420a846f53ea0789ebfb0ad", "0x1193d170b0b2dd0c4a04331a4b4aa3f12920f182ec3ab547837e30f1116ca584", "0x00000000000000000000000000000025704a15c9e2ce8a69558e7bbcdcbc7784", "0x2e5d36112770fb6c985681cafe40a8c99ad13f702309e7969801dd0ed080e727", "0x0eefc2585f591bb457183134e19ad643966272234d645514bf7868d6dd8ae2cb", "0x300803e4e2339ad39b9c31f228949bbeaf9c74b7101e7be1930b088126247eaa", "0x2bb562a50ed944b438b83b01f200101a34faef7f296a75c84c731755ebddbc1a", "0x1288e0b9c742af39cbcac21357c1b29511b0bbdd3d0e3cf5e14b2eef68a28ab3", "0x20f089131cc96d86ff1cfb67fa3f51670f4bad30158751b2587354bbec76cdf9", "0x1a26c6d3e633f9bf8434cf755b5f1217dad0d455071a97a7bcf85b824f5cf07a", "0x0d7e9b8a51fccf910ec25bdbd13e70b34bd6ea6f4d629fa744f9cdf5f2beb1cf", "0x0b40f28ce428e64df9cf5a024133fc420f39decf5f6af020cc3211ab298d4631", "0x0ca4f189dde7a55fe829f46681232904f6670249a22e0deb47222bd309523a8a", "0x2c544f2e31143783977645edb2a6bdb39b875053963bfa1a5b3ae9de204a7ebe", "0x00aae4454eb48fb18ff60db6b9d015abea2e770a2f7d86d121522b834c791ba5", "0x07d74e351fd4cccf4e18475d25211efa8a359066fc693a5c8505ddb507e4b74b", "0x07d74e351fd4cccf4e18475d25211efa8a359066fc693a5c8505ddb507e4b74b", "0x2d9e5bff47207d82533e2445959941181cc890c5779bc7f24d6e8a7b9e425b5c", "0x0aea3c0c317c441a5775a9849108d7a6889b39128235f717b09b184aa08e4eb7", "0x1ca5bc6fb37c55a562f4991901c39902f42d14db71284116df74cb4e7d55e493", "0x220fed26d64cd69f40e6d145a423e4a3c8cd0dce747e7d51647441270ad4d774", "0x15be574c9358889257aa2a30ff7b5fcc31a57da7032296e2c1201c49a44bbdb6", "0x2de539925525bedd3b7f43a9c6bf0f713151a17f79ac7ff4a9cd27b15ffe892a", "0x083086693dbf465211741e2cbff70ff38eb08383faf22d397eb2742c8ad7396a", "0x1fdfa258a890598816e807c50058d7a1462edd5ff196a2eae0f862e454b49aa1", "0x10c434c6daaa8226fa8e3e302123dfdc4455cf68063df518949df5a65a945213", "0x0000000000000000000000000000006472a7874de2c454a4591ed7784df1c104", "0x000000000000000000000000000000000008c46ac53d2c4ad0c26a5d6c790082", "0x0000000000000000000000000000005e422f9cfb8725800de60dfe0a8d4104c0", "0x000000000000000000000000000000000000f10fd4e4de81a0c00073ec91c274", "0x000000000000000000000000000000b20813090eca76bc6aa4a699b1ec8d5d6d", "0x0000000000000000000000000000000000292cc9f8a744eb00e0903c29ce87a7", "0x000000000000000000000000000000350a368b415fbb99fa90a26a42b1a3affd", "0x0000000000000000000000000000000000280eb9275cb05a3435f464d1dc369d", "0x000000000000000000000000000000280df6505e20c7725fe6d29439f96ee05d", "0x000000000000000000000000000000000017ef5033a08535451e2747827aa94b", "0x0000000000000000000000000000002f9ba89ae91b4e4a4ff8ccbd0526faad2f", "0x00000000000000000000000000000000001c2013561dafcc02cb03220bdf23c4", "0x000000000000000000000000000000aac102c400f9e5da0321ded4510994434b", "0x00000000000000000000000000000000001ec8ab9cc834b492fde124962f04a1", "0x0000000000000000000000000000000673dbd698da8b8cce450d2a083aba9987", "0x00000000000000000000000000000000000a49e55bb040249cb41c63cea901cd", "0x000000000000000000000000000000133d92af8d76ee0c74a12081ee7b2ef8c4", "0x0000000000000000000000000000000000240f552d1c6cbb007650e4b142e0a5", "0x000000000000000000000000000000e29c6e7d982ec08d51c79d6261c28d742d", "0x000000000000000000000000000000000021baeec04d9be419c923626034e7b3", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x1e940a528b42d8230e7d4dff76262a80986c0d00b2c02a9bc0559e36212d1547", "0x1ceccf21ac39f70d76ad6f7fe0dcb33b6af04555a0b1959e4714d65925e4e253", "0x096139d757046cdbdb7ee89a95f112f70882a43a46c2f739d9be115dda013420", "0x2f9c8ac67c7825b08eff0e7f7656a671f4c64e5601f2efab35b1b795801eec04", "0x2077e648e1704851cdffd7e6e56311634a7b741bab77ca34d9dff12a6a2bfe99", "0x115d48c4a97aeb3c447a060f9e0d675b0dc7f4a05a3f5776e2f279f3a165d7dc", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x000000000000000000000000000000fd38c45c3ec5b841482a80e3a56ce82555", "0x00000000000000000000000000000000000ad70b03f092f60af3e0ce1bb29d2c", "0x0000000000000000000000000000007a184d5342c90c634c0b1a050f0b97c9fb", "0x0000000000000000000000000000000000271f42abcb3bc1f0332e4b3ca85e1d", "0x0000000000000000000000000000008256322bbe2c1b8cd9d84e5ff6123477f2", "0x000000000000000000000000000000000025cab962761681dd9547f4c78814df", "0x0000000000000000000000000000008c4234510e5825c02b9ac427bcbf8e279a", "0x000000000000000000000000000000000013a14e0d7fc073c44643af38cc5396"] -public_inputs = ["0x0000000000000000000000000000000000000000000000000000000000000003"] -verification_key = ["0x0000000000000000000000000000000000000000000000000000000000000040", "0x0000000000000000000000000000000000000000000000000000000000000011", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000003", "0x0000000000000000000000000000000000000000000000000000000000000004", "0x0000000000000000000000000000000000000000000000000000000000000005", "0x0000000000000000000000000000000000000000000000000000000000000006", "0x0000000000000000000000000000000000000000000000000000000000000007", "0x0000000000000000000000000000000000000000000000000000000000000008", "0x0000000000000000000000000000000000000000000000000000000000000009", "0x000000000000000000000000000000000000000000000000000000000000000a", "0x000000000000000000000000000000000000000000000000000000000000000b", "0x000000000000000000000000000000000000000000000000000000000000000c", "0x000000000000000000000000000000000000000000000000000000000000000d", "0x000000000000000000000000000000000000000000000000000000000000000e", "0x000000000000000000000000000000000000000000000000000000000000000f", "0x0000000000000000000000000000000000000000000000000000000000000010", "0x00000000000000000000000000000060e430ad1c23bfcf3514323aae3f206e84", "0x00000000000000000000000000000000001b5c3ff4c2458d8f481b1c068f27ae", "0x000000000000000000000000000000bb510ab2112def34980e4fc6998ad9dd16", "0x00000000000000000000000000000000000576e7c105b43e061e13cb877fefe1", "0x000000000000000000000000000000ced074785d11857b065d8199e6669a601c", "0x00000000000000000000000000000000000053b48a4098c1c0ae268f273952f7", "0x000000000000000000000000000000d1d4b26e941db8168cee8f6de548ae0fd8", "0x00000000000000000000000000000000001a9adf5a6dadc3d948bb61dfd63f4c", "0x0000000000000000000000000000009ce1faac6f8de6ebb18f1db17372c82ad5", "0x00000000000000000000000000000000002002681bb417184b2df070a16a3858", "0x000000000000000000000000000000161baa651a8092e0e84725594de5aba511", "0x00000000000000000000000000000000000be0064399c2a1efff9eb0cdcb2223", "0x0000000000000000000000000000008673be6fd1bdbe980a29d8c1ded54381e7", "0x000000000000000000000000000000000008a5158a7d9648cf1d234524c9fa0c", "0x0000000000000000000000000000002b4fce6e4b1c72062b296d49bca2aa4130", "0x00000000000000000000000000000000002e45a9eff4b6769e55fb710cded44f", "0x00000000000000000000000000000072b85bf733758b76bcf97333efb85a23e3", "0x000000000000000000000000000000000017da0ea508994fc82862715e4b5592", "0x00000000000000000000000000000094fa74695cf058dba8ff35aec95456c6c3", "0x0000000000000000000000000000000000211acddb851061c24b8f159e832bd1", "0x000000000000000000000000000000303b5e5c531384b9a792e11702ad3bcab0", "0x00000000000000000000000000000000000d336dff51a60b8833d5d7f6d4314c", "0x0000000000000000000000000000009f825dde88092070747180d581c342444a", "0x0000000000000000000000000000000000237fbd6511a03cca8cac01b555fe01", "0x0000000000000000000000000000007c313205159495df6d8de292079a4844ff", "0x000000000000000000000000000000000018facdfc468530dd45e8f7a1d38ce9", "0x0000000000000000000000000000000d1ce33446fc3dc4ab40ca38d92dac74e1", "0x00000000000000000000000000000000000852d8e3e0e8f4435af3e94222688b", "0x0000000000000000000000000000006c04ee19ec1dfec87ed47d6d04aa158de2", "0x000000000000000000000000000000000013240f97a584b45184c8ec31319b5f", "0x000000000000000000000000000000cefb5d240b07ceb4be26ea429b6dc9d9e0", "0x00000000000000000000000000000000002dad22022121d689f57fb38ca21349", "0x000000000000000000000000000000c9f189f2a91aeb664ce376d8b157ba98f8", "0x00000000000000000000000000000000002531a51ad54f124d58094b219818d2", "0x000000000000000000000000000000ef1e6db71809307f677677e62b4163f556", "0x0000000000000000000000000000000000272da4396fb2a7ee0638b9140e523d", "0x0000000000000000000000000000002e54c0244a7732c87bc4712a76dd8c83fb", "0x000000000000000000000000000000000007db77b3e04b7eba9643da57cbbe4d", "0x000000000000000000000000000000e0dfe1ddd7f74ae0d636c910c3e85830d8", "0x00000000000000000000000000000000000466fa9b57ec4664abd1505b490862", "0x0000000000000000000000000000009ee55ae8a32fe5384c79907067cc27192e", "0x00000000000000000000000000000000000799d0e465cec07ecb5238c854e830", "0x0000000000000000000000000000001d5910ad361e76e1c241247a823733c39f", "0x00000000000000000000000000000000002b03f2ccf7507564da2e6678bef8fe", "0x000000000000000000000000000000ee40d90bea71fba7a412dd61fcf34e8ceb", "0x0000000000000000000000000000000000140b0936c323fd2471155617b6af56", "0x0000000000000000000000000000002b90071823185c5ff8e440fd3d73b6fefc", "0x00000000000000000000000000000000002b6c10790a5f6631c87d652e059df4", "0x00000000000000000000000000000029a17181c7934fc3fdbd352eac5cb521b9", "0x00000000000000000000000000000000001f497cbf5284ff29a2d336e5991999", "0x000000000000000000000000000000072bd9c0c6beda1fdee6d4ff0432ba9e1b", "0x000000000000000000000000000000000013ea38a0bd2aa751a490a724fac818", "0x000000000000000000000000000000c599f63dcd3edd49f08ae5c3141c1e3493", "0x00000000000000000000000000000000002bdb36be0bea09950dd32a8ccf6fbc", "0x00000000000000000000000000000047f27f29724e7f19eba0340256a0bd4b7d", "0x00000000000000000000000000000000001c1c5ccf87a962129ca785f8f35120", "0x000000000000000000000000000000c5c71efdae00679bbe4a95096e012b1817", "0x000000000000000000000000000000000017a365de041e317817d0135f2b48e0", "0x0000000000000000000000000000008ae711ac402f7848d719c93a89ba8d39f1", "0x00000000000000000000000000000000002b6fb40ed8a1935226f4f9786a0499", "0x0000000000000000000000000000002f03a71501d83de1da5715a4e9462d6198", "0x00000000000000000000000000000000001644064443b8546f48eae693af47b8", "0x00000000000000000000000000000083763ab1b6e8fe269b2fe4c7b9c448c08d", "0x000000000000000000000000000000000021d7cc18c59676a8eeb47c0111c251", "0x000000000000000000000000000000b5f937153073e03ea7d51a996e0ebc2e6b", "0x000000000000000000000000000000000011ddd0e26457373eb06e0493177672", "0x000000000000000000000000000000c5f6eb9f6fc8fa99811a4a88c74a6d018b", "0x000000000000000000000000000000000025bcd07a0732c123567834f5109558", "0x000000000000000000000000000000aeb08a0b1a4442189448b4e97490568146", "0x000000000000000000000000000000000002a1744e4771705536a88f07e0f90f", "0x000000000000000000000000000000b938568293bd0724b0ea76c2ec34c4a829", "0x0000000000000000000000000000000000053296e8f3b9ad3af877dfa9c7c2a7", "0x000000000000000000000000000000f0ca1db6323996eba26bdc86dafef9d10b", "0x00000000000000000000000000000000001441a46c58af03d5645d52721d956a", "0x0000000000000000000000000000008bbf8f884013c66c28ba09c2fbd573b656", "0x0000000000000000000000000000000000206c391ca06fac27d1908e94570243", "0x0000000000000000000000000000002d4f5aaed88ba4f79612d53b804ca8f194", "0x00000000000000000000000000000000001674011c96392df08970fa6b7b4cb8", "0x0000000000000000000000000000009f88297c1729d76c4d9306853598c91325", "0x0000000000000000000000000000000000256f51adfcacc3c1e340be4d32d3e9", "0x0000000000000000000000000000000ab9955eec0d74eb799afed2a802b24d75", "0x00000000000000000000000000000000001fcbe43ea105b30d36ed0b21b03411", "0x000000000000000000000000000000d66b1d5433f1aa5305cd1edce7c22de466", "0x00000000000000000000000000000000002331546a256b8a3b751956806680d4", "0x000000000000000000000000000000e97954ad6cd6f45fb15c91434121db4304", "0x00000000000000000000000000000000002e20a97e09d50f227ced47e7a98250", "0x0000000000000000000000000000001ebbc27eb9ebededefba79522eb58ae89b", "0x0000000000000000000000000000000000090efa4974e566e81d1177b85a30be", "0x0000000000000000000000000000005eafa070b9c9632404052642e3bc14f9fd", "0x00000000000000000000000000000000001489068864102daca6a6b8bc4d448b", "0x0000000000000000000000000000009ebc91aaaac036a6477cadbe54e8556dfd", "0x00000000000000000000000000000000000ef6d835e2ed3343b95c82c8c54037", "0x00000000000000000000000000000033b28b529dff46e93af4e7422530478e4a", "0x000000000000000000000000000000000020a86c2f8591bf190bcddcc03c42fb", "0x000000000000000000000000000000a9679d0acc088f7dc27bf6d866bcd2dda2", "0x00000000000000000000000000000000002fb9d0d2d4099402bed74f738f64cc", "0x00000000000000000000000000000023b09f876a29a061582848a8b9a5870c12", "0x00000000000000000000000000000000001d5bb906f03f0d49e9c4791bc43af9", "0x00000000000000000000000000000017aac9854ea240d8ec97bf760c4d4ba870", "0x00000000000000000000000000000000000b227a556c414ada0dc75bb303e30e", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000009b624fa65d1a24b7f14a8f25f3789622af", "0x000000000000000000000000000000000013d47bff8c630e847b70e2732fd3f0", "0x00000000000000000000000000000061d21663e93132f32921075f4c936a84df", "0x00000000000000000000000000000000001a74ca4e118fb480b9b999902989a3"] -proof_b = ["0x0000000000000000000000000000000000000000000000000000000000000040", "0x0000000000000000000000000000000000000000000000000000000000000011", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000042ab5d6d1986846cf", "0x00000000000000000000000000000000000000000000000b75c020998797da78", "0x0000000000000000000000000000000000000000000000005a107acb64952eca", "0x000000000000000000000000000000000000000000000000000031e97a575e9d", "0x00000000000000000000000000000000000000000000000b5666547acf8bd5a4", "0x00000000000000000000000000000000000000000000000c410db10a01750aeb", "0x00000000000000000000000000000000000000000000000d722669117f9758a4", "0x000000000000000000000000000000000000000000000000000178cbf4206471", "0x000000000000000000000000000000000000000000000000e91b8a11e7842c38", "0x000000000000000000000000000000000000000000000007fd51009034b3357f", "0x000000000000000000000000000000000000000000000009889939f81e9c7402", "0x0000000000000000000000000000000000000000000000000000f94656a2ca48", "0x000000000000000000000000000000000000000000000006fb128b46c1ddb67f", "0x0000000000000000000000000000000000000000000000093fe27776f50224bd", "0x000000000000000000000000000000000000000000000004a0c80c0da527a081", "0x0000000000000000000000000000000000000000000000000001b52c2020d746", "0x0000000000000000000000000000005a9bae947e1e91af9e4033d8d6aa6ed632", "0x000000000000000000000000000000000025e485e013446d4ac7981c88ba6ecc", "0x000000000000000000000000000000ff1e0496e30ab24a63b32b2d1120b76e62", "0x00000000000000000000000000000000001afe0a8a685d7cd85d1010e55d9d7c", "0x000000000000000000000000000000b0804efd6573805f991458295f510a2004", "0x00000000000000000000000000000000000c81a178016e2fe18605022d5a8b0e", "0x000000000000000000000000000000eba51e76eb1cfff60a53a0092a3c3dea47", "0x000000000000000000000000000000000022e7466247b533282f5936ac4e6c15", "0x00000000000000000000000000000071b1d76edf770edff98f00ff4deec264cd", "0x00000000000000000000000000000000001e48128e68794d8861fcbb2986a383", "0x000000000000000000000000000000d3a2af4915ae6d86b097adc377fafda2d4", "0x000000000000000000000000000000000006359de9ca452dab3a4f1f8d9c9d98", "0x0000000000000000000000000000006cf7dd96d7636fda5953191b1ad776d491", "0x00000000000000000000000000000000001633d881a08d136e834cb13a28fcc6", "0x00000000000000000000000000000001254956cff6908b069fca0e6cf1c47eb1", "0x000000000000000000000000000000000006f4d4dd3890e997e75e75886bf8f7", "0x0000000000000000000000000000006cf7dd96d7636fda5953191b1ad776d491", "0x00000000000000000000000000000000001633d881a08d136e834cb13a28fcc6", "0x00000000000000000000000000000001254956cff6908b069fca0e6cf1c47eb1", "0x000000000000000000000000000000000006f4d4dd3890e997e75e75886bf8f7", "0x000000000000000000000000000000f968b227a358a305607f3efc933823d288", "0x00000000000000000000000000000000000eaf8adb390375a76d95e918b65e08", "0x000000000000000000000000000000bb34b4b447aae56f5e24f81c3acd6d547f", "0x00000000000000000000000000000000002175d012746260ebcfe339a91a81e1", "0x00000000000000000000000000000052eebbd1f6f7554e837f60c44000ed14b6", "0x00000000000000000000000000000000001c1c045a3ec94b8801f2272cc0b3f4", "0x0000000000000000000000000000004d2ef74134578f6b431a9df071ffca4292", "0x0000000000000000000000000000000000291326ade7aa6f0dfc8900eab5580b", "0x0000000000000000000000000000002433eec6418a6dba820c9527e2581fc8bc", "0x00000000000000000000000000000000000e88b7daad19af2ac2f9bdf9e50ee2", "0x000000000000000000000000000000dcfce2c427155cc3e4d035735d3dd5ece8", "0x00000000000000000000000000000000002d7d473cac1a15d0fee8b22c1a7b3e", "0x1a4249b90be4602c8ff40c7c276160ee41b2a0f8a238ce7706e9face2db03d48", "0x162204b9d54d3ffd285c393a5a1ff76ee681474fd780a21a3cf7fac5c24fc2b9", "0x30279eb953d8ee79b2155c69c04e6443c5de6bf7e02886256dd7b3cd3c9502a4", "0x0d32c1bd21baf43e72d5d82d461ef54833807ff81a877adc822f27a6db88d754", "0x0fe15e055c0803d5ebe6dd77689b70cfd82138f008810ce24535c992daaff27d", "0x1fba82c012671212ce2fc13fd09bf8fba4f7d5875ab8d37495d1ccfcff287331", "0x090738a5842fa4d2699b3726aa0dd97cb59569b4be2c6825335ec4969f859dc2", "0x0c6cb72dabbc28abcf4a50c203534e066c29f48c24ca64d672092f263df3f9d7", "0x0f27fbea0d9145f815c288b50fe7e8c10b8185d325b5264624fd57102855d05d", "0x2a815cd3fd1c43c72ee0130465250ff771d1e7be2347e4ada331b83265a03450", "0x148b4ecf2ad7ed17409417086867ee27bc1b0906dbc9cbb3714c285071e2db70", "0x08e700a42b1d6d36ee65f8ebedf47d3a44463ff9fa579dce13b7492e20142c3a", "0x2e23c69521d572ff2152c50f8c9a9191535f4cf37f95f1e0428692e78842b642", "0x14519e0354365923fb41400c19866135b45e975d56a0980260bc99f0390b1d5f", "0x04caded1f05738f736cb5bcf08d785e395e58eb7738523a20638aa16bc51593e", "0x28787eaccd38383215ea21ec02895c32d979f68ca155f534a2e2d377bff6698b", "0x20a1b81fa96c58cf11c5762c5ceb731efdcb081fca2d34d5c463d2cf40e6da18", "0x11789a06fe3bf53833741d180f068d29534d5bb58a5c64b8119542e62b189fb4", "0x23d00fcd032ace719ffcbc513bfa177a55b04377d76455c2788d999d05d011e2", "0x01f0e81b57b4a73cc118e51ede18f8724debf25c2d109db6ef45280f99f1a3fa", "0x156d1c9b61749810de728f259c2c1c1fd4dbff97101426e26087ca461c93307c", "0x1c5d619ac3a478cfd06d5eebfd879960bb321236be173813f5e78d1366d32c69", "0x250cfae4e1dfc551406f1f3d10b649a637dcb7bcb0f6f697994cf96afd35d0c1", "0x242b999f58cf5f53c874d1092bd38725aa9ea076f5bc8f176efa9ea23393874b", "0x2e15748255c4a5e0e9fe38047341b692a967257de27a85a3a38681bc9f1602ea", "0x01ef83886ea7017253699cb6371988eb8e21b4f7023d7479ece4907fe6d4a6fd", "0x08db2dbc271e375b9312f695c59c48f313235b3432cad50921c8d9ad6dd7ad7a", "0x199309f2c2cd45c15a4abb0e6554a1615ff5a6e9488a8d900bbf835fc8f664ef", "0x074be7a3d88e31ab1b59c9208c012bcfb1f85f351c709e68134996891db52b57", "0x301b1011354d2ebf46134fc4d6d734bb6ed8542d719f38f5e09a376a580cad7f", "0x12968f3eccaa27e44f14d5aaac6ecb70c00d040e07536292e685d7cab03fc563", "0x2110a023c8c22fd2ed70270a2d0a265b92a32ce2217ffe1be9a5d7d5c25f512f", "0x1e8cf4c60c53900f0430d5b44de5804fe8b38299bc803beeb4216e1a289cf624", "0x12301cb908ccb28a2616e29b831ec7105b5d3ebf45ff5fe91d50a9dd53a50b52", "0x0f1029ed107d84ff2d6d4a416cbd01da3f3d7bf5b2209ce93ba424f4b85616fc", "0x1b431d016611b8abd684afd9e92331c3325967b1116bfa91d4f44e2f8e2c9fc2", "0x281e335a0fd117064c8ace3f01e02b134a19e9b9220571ebfaaaa0e3a12d34db", "0x22559c106f77e2ae95677d5e38e288343e3b7168371aec7d3aaab9ef8150af70", "0x13f113b1d9b590149cf08c3f6e90589cda5c7b98528866b891256cb9d5d814e7", "0x10252ef388e4c80246962e98b9e976fab2cd25e1e6f1e3fd2a7d4786c5218a97", "0x16b890723dfdebd9912a9207255f95cb800222165b6fae97ec46e461f23e83f3", "0x25caf77c7d2e8e069341ec90f3c8f6d64319cfd2d77cab0625cf0377285ba11c", "0x016c84288b0bc3c50eebbe250cdd5a4ee50b2c65a24ac64d0c930cbdecb95141", "0x20a537c045b069d47dc6315f45b391f60681222381e5059ec7c8b17bf677d911", "0x2594c0edfcd4064d215a3d797bc8e3b2f401c61f3961ae96ccbec8f8fd29e81f", "0x1c831d7047483ca00ed59bdb84c47ffb8bbebbae92aa164c7b35fcffbb8a35d3", "0x2ea7f60de52b8cd6b0bd06f861fc1f2c5ed1d1fbfa53caccdb836400a03df434", "0x275c6c8bd115f7d2ce196439e2330fad305c6745bab0bf1ce3f2fa32dadc3c43", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x2b3f4e210619347288731e7f0eea1ae60dd8696fe87319044864d099a03a9536", "0x0fecd3d2aebedeb8be2b0b7e3a74de9ec8bd2cb72851541463729e0715aef48b", "0x10bee385ad0c2cd3ff88ef4d630840749e4367f9add4a300fc4f545a7778e92c", "0x1fe792730eeafbd22c4eb80e86e2b40108b1e55b2a08db786289eea5745b9e3b", "0x04d411679da432816b213cd5580dda1fd6c2f258684c036be19b5b26baca583c", "0x159f17b655d2b8a803e0cfb564918628be52d3baa950ca1b127854491624f8f4", "0x225340463867d9252a1269013536e2e1dd219aa18eadef13c324b63d44679334", "0x1885e231554e02abb40ed54b72ebf09b883d0298a6bc06fc645a30365f370ef2", "0x233344517f25170972b8ba35d01f2df2e073d322993abce7df26796126e93498", "0x08990e8faa13b18b4433ec417c5cc596885e11ffd372d5f612c08cc79a5d5c80", "0x1e960a0c892b755c28e21dcbed816c1b182d7da43bae07f8ee622bd4485f79e7", "0x27b58e2ee290a179d349ace82752528b2ff946d60c092b99ef42f53c25d0c99f", "0x2a5cf8a3193107d982edd253002c7a52ab876b445dde8307ab78fbdca022d93c", "0x2b1ab4d5277f8c82750c1c7bd043889b71465ec64a9afc1bfa37d06b1ebd0725", "0x2a0dbf5c4373a58a83d5f2a031ea0615bf12800e33b70c3191a7cbb15966ced8", "0x1f272bb4a19d14a0abdfebc9fc83125e10623b9aef730f8d25f2bf5bead38ea9", "0x2c2339cf0ae7aff56091a568c1e2c3f01f52d8ed13400737fd31eaabcaffb9bd", "0x21f5fefe6b5fa0b5da71089befb74a1a39e52b4f830cb330c3c284e154614dfd", "0x1e6f6ba4b2444586b380dc4e2b3fad111ff1f4754420a846f53ea0789ebfb0ad", "0x1193d170b0b2dd0c4a04331a4b4aa3f12920f182ec3ab547837e30f1116ca584", "0x00000000000000000000000000000025704a15c9e2ce8a69558e7bbcdcbc7784", "0x2e5d36112770fb6c985681cafe40a8c99ad13f702309e7969801dd0ed080e727", "0x0eefc2585f591bb457183134e19ad643966272234d645514bf7868d6dd8ae2cb", "0x300803e4e2339ad39b9c31f228949bbeaf9c74b7101e7be1930b088126247eaa", "0x2bb562a50ed944b438b83b01f200101a34faef7f296a75c84c731755ebddbc1a", "0x1288e0b9c742af39cbcac21357c1b29511b0bbdd3d0e3cf5e14b2eef68a28ab3", "0x20f089131cc96d86ff1cfb67fa3f51670f4bad30158751b2587354bbec76cdf9", "0x1a26c6d3e633f9bf8434cf755b5f1217dad0d455071a97a7bcf85b824f5cf07a", "0x0d7e9b8a51fccf910ec25bdbd13e70b34bd6ea6f4d629fa744f9cdf5f2beb1cf", "0x0b40f28ce428e64df9cf5a024133fc420f39decf5f6af020cc3211ab298d4631", "0x0ca4f189dde7a55fe829f46681232904f6670249a22e0deb47222bd309523a8a", "0x2c544f2e31143783977645edb2a6bdb39b875053963bfa1a5b3ae9de204a7ebe", "0x00aae4454eb48fb18ff60db6b9d015abea2e770a2f7d86d121522b834c791ba5", "0x07d74e351fd4cccf4e18475d25211efa8a359066fc693a5c8505ddb507e4b74b", "0x07d74e351fd4cccf4e18475d25211efa8a359066fc693a5c8505ddb507e4b74b", "0x2d9e5bff47207d82533e2445959941181cc890c5779bc7f24d6e8a7b9e425b5c", "0x0aea3c0c317c441a5775a9849108d7a6889b39128235f717b09b184aa08e4eb7", "0x1ca5bc6fb37c55a562f4991901c39902f42d14db71284116df74cb4e7d55e493", "0x220fed26d64cd69f40e6d145a423e4a3c8cd0dce747e7d51647441270ad4d774", "0x15be574c9358889257aa2a30ff7b5fcc31a57da7032296e2c1201c49a44bbdb6", "0x2de539925525bedd3b7f43a9c6bf0f713151a17f79ac7ff4a9cd27b15ffe892a", "0x083086693dbf465211741e2cbff70ff38eb08383faf22d397eb2742c8ad7396a", "0x1fdfa258a890598816e807c50058d7a1462edd5ff196a2eae0f862e454b49aa1", "0x10c434c6daaa8226fa8e3e302123dfdc4455cf68063df518949df5a65a945213", "0x0000000000000000000000000000006472a7874de2c454a4591ed7784df1c104", "0x000000000000000000000000000000000008c46ac53d2c4ad0c26a5d6c790082", "0x0000000000000000000000000000005e422f9cfb8725800de60dfe0a8d4104c0", "0x000000000000000000000000000000000000f10fd4e4de81a0c00073ec91c274", "0x000000000000000000000000000000b20813090eca76bc6aa4a699b1ec8d5d6d", "0x0000000000000000000000000000000000292cc9f8a744eb00e0903c29ce87a7", "0x000000000000000000000000000000350a368b415fbb99fa90a26a42b1a3affd", "0x0000000000000000000000000000000000280eb9275cb05a3435f464d1dc369d", "0x000000000000000000000000000000280df6505e20c7725fe6d29439f96ee05d", "0x000000000000000000000000000000000017ef5033a08535451e2747827aa94b", "0x0000000000000000000000000000002f9ba89ae91b4e4a4ff8ccbd0526faad2f", "0x00000000000000000000000000000000001c2013561dafcc02cb03220bdf23c4", "0x000000000000000000000000000000aac102c400f9e5da0321ded4510994434b", "0x00000000000000000000000000000000001ec8ab9cc834b492fde124962f04a1", "0x0000000000000000000000000000000673dbd698da8b8cce450d2a083aba9987", "0x00000000000000000000000000000000000a49e55bb040249cb41c63cea901cd", "0x000000000000000000000000000000133d92af8d76ee0c74a12081ee7b2ef8c4", "0x0000000000000000000000000000000000240f552d1c6cbb007650e4b142e0a5", "0x000000000000000000000000000000e29c6e7d982ec08d51c79d6261c28d742d", "0x000000000000000000000000000000000021baeec04d9be419c923626034e7b3", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x1e940a528b42d8230e7d4dff76262a80986c0d00b2c02a9bc0559e36212d1547", "0x1ceccf21ac39f70d76ad6f7fe0dcb33b6af04555a0b1959e4714d65925e4e253", "0x096139d757046cdbdb7ee89a95f112f70882a43a46c2f739d9be115dda013420", "0x2f9c8ac67c7825b08eff0e7f7656a671f4c64e5601f2efab35b1b795801eec04", "0x2077e648e1704851cdffd7e6e56311634a7b741bab77ca34d9dff12a6a2bfe99", "0x115d48c4a97aeb3c447a060f9e0d675b0dc7f4a05a3f5776e2f279f3a165d7dc", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x000000000000000000000000000000fd38c45c3ec5b841482a80e3a56ce82555", "0x00000000000000000000000000000000000ad70b03f092f60af3e0ce1bb29d2c", "0x0000000000000000000000000000007a184d5342c90c634c0b1a050f0b97c9fb", "0x0000000000000000000000000000000000271f42abcb3bc1f0332e4b3ca85e1d", "0x0000000000000000000000000000008256322bbe2c1b8cd9d84e5ff6123477f2", "0x000000000000000000000000000000000025cab962761681dd9547f4c78814df", "0x0000000000000000000000000000008c4234510e5825c02b9ac427bcbf8e279a", "0x000000000000000000000000000000000013a14e0d7fc073c44643af38cc5396"] \ No newline at end of file diff --git a/noir/noir-repo/test_programs/execution_success/double_verify_honk_proof/src/main.nr b/noir/noir-repo/test_programs/execution_success/double_verify_honk_proof/src/main.nr deleted file mode 100644 index aecaa931d43..00000000000 --- a/noir/noir-repo/test_programs/execution_success/double_verify_honk_proof/src/main.nr +++ /dev/null @@ -1,28 +0,0 @@ -// This circuit aggregates two Honk proof from `assert_statement_recursive`. -global SIZE_OF_PROOF_IF_LOGN_IS_28: u32 = 463; -global HONK_IDENTIFIER: u32 = 1; -fn main( - verification_key: [Field; 128], - // This is the proof without public inputs attached. - // This means: the size of this does not change with the number of public inputs. - proof: [Field; SIZE_OF_PROOF_IF_LOGN_IS_28], - public_inputs: pub [Field; 1], - key_hash: Field, - // The second proof, currently set to be identical - proof_b: [Field; SIZE_OF_PROOF_IF_LOGN_IS_28], -) { - std::verify_proof_with_type( - verification_key, - proof, - public_inputs, - key_hash, - HONK_IDENTIFIER, - ); - std::verify_proof_with_type( - verification_key, - proof_b, - public_inputs, - key_hash, - HONK_IDENTIFIER, - ); -} diff --git a/noir/noir-repo/test_programs/execution_success/double_verify_honk_proof_recursive/Nargo.toml b/noir/noir-repo/test_programs/execution_success/double_verify_honk_proof_recursive/Nargo.toml deleted file mode 100644 index 618ba8a87b7..00000000000 --- a/noir/noir-repo/test_programs/execution_success/double_verify_honk_proof_recursive/Nargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "double_verify_honk_proof_recursive" -type = "bin" -authors = [""] - -[dependencies] diff --git a/noir/noir-repo/test_programs/execution_success/double_verify_honk_proof_recursive/Prover.toml b/noir/noir-repo/test_programs/execution_success/double_verify_honk_proof_recursive/Prover.toml deleted file mode 100644 index f8e7ba41a18..00000000000 --- a/noir/noir-repo/test_programs/execution_success/double_verify_honk_proof_recursive/Prover.toml +++ /dev/null @@ -1,5 +0,0 @@ -key_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" -proof = ["0x0000000000000000000000000000000000000000000000000000000000000040", "0x0000000000000000000000000000000000000000000000000000000000000011", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000042ab5d6d1986846cf", "0x00000000000000000000000000000000000000000000000b75c020998797da78", "0x0000000000000000000000000000000000000000000000005a107acb64952eca", "0x000000000000000000000000000000000000000000000000000031e97a575e9d", "0x00000000000000000000000000000000000000000000000b5666547acf8bd5a4", "0x00000000000000000000000000000000000000000000000c410db10a01750aeb", "0x00000000000000000000000000000000000000000000000d722669117f9758a4", "0x000000000000000000000000000000000000000000000000000178cbf4206471", "0x000000000000000000000000000000000000000000000000e91b8a11e7842c38", "0x000000000000000000000000000000000000000000000007fd51009034b3357f", "0x000000000000000000000000000000000000000000000009889939f81e9c7402", "0x0000000000000000000000000000000000000000000000000000f94656a2ca48", "0x000000000000000000000000000000000000000000000006fb128b46c1ddb67f", "0x0000000000000000000000000000000000000000000000093fe27776f50224bd", "0x000000000000000000000000000000000000000000000004a0c80c0da527a081", "0x0000000000000000000000000000000000000000000000000001b52c2020d746", "0x0000000000000000000000000000005a9bae947e1e91af9e4033d8d6aa6ed632", "0x000000000000000000000000000000000025e485e013446d4ac7981c88ba6ecc", "0x000000000000000000000000000000ff1e0496e30ab24a63b32b2d1120b76e62", "0x00000000000000000000000000000000001afe0a8a685d7cd85d1010e55d9d7c", "0x000000000000000000000000000000b0804efd6573805f991458295f510a2004", "0x00000000000000000000000000000000000c81a178016e2fe18605022d5a8b0e", "0x000000000000000000000000000000eba51e76eb1cfff60a53a0092a3c3dea47", "0x000000000000000000000000000000000022e7466247b533282f5936ac4e6c15", "0x00000000000000000000000000000071b1d76edf770edff98f00ff4deec264cd", "0x00000000000000000000000000000000001e48128e68794d8861fcbb2986a383", "0x000000000000000000000000000000d3a2af4915ae6d86b097adc377fafda2d4", "0x000000000000000000000000000000000006359de9ca452dab3a4f1f8d9c9d98", "0x0000000000000000000000000000006cf7dd96d7636fda5953191b1ad776d491", "0x00000000000000000000000000000000001633d881a08d136e834cb13a28fcc6", "0x00000000000000000000000000000001254956cff6908b069fca0e6cf1c47eb1", "0x000000000000000000000000000000000006f4d4dd3890e997e75e75886bf8f7", "0x0000000000000000000000000000006cf7dd96d7636fda5953191b1ad776d491", "0x00000000000000000000000000000000001633d881a08d136e834cb13a28fcc6", "0x00000000000000000000000000000001254956cff6908b069fca0e6cf1c47eb1", "0x000000000000000000000000000000000006f4d4dd3890e997e75e75886bf8f7", "0x000000000000000000000000000000f968b227a358a305607f3efc933823d288", "0x00000000000000000000000000000000000eaf8adb390375a76d95e918b65e08", "0x000000000000000000000000000000bb34b4b447aae56f5e24f81c3acd6d547f", "0x00000000000000000000000000000000002175d012746260ebcfe339a91a81e1", "0x00000000000000000000000000000052eebbd1f6f7554e837f60c44000ed14b6", "0x00000000000000000000000000000000001c1c045a3ec94b8801f2272cc0b3f4", "0x0000000000000000000000000000004d2ef74134578f6b431a9df071ffca4292", "0x0000000000000000000000000000000000291326ade7aa6f0dfc8900eab5580b", "0x0000000000000000000000000000002433eec6418a6dba820c9527e2581fc8bc", "0x00000000000000000000000000000000000e88b7daad19af2ac2f9bdf9e50ee2", "0x000000000000000000000000000000dcfce2c427155cc3e4d035735d3dd5ece8", "0x00000000000000000000000000000000002d7d473cac1a15d0fee8b22c1a7b3e", "0x1a4249b90be4602c8ff40c7c276160ee41b2a0f8a238ce7706e9face2db03d48", "0x162204b9d54d3ffd285c393a5a1ff76ee681474fd780a21a3cf7fac5c24fc2b9", "0x30279eb953d8ee79b2155c69c04e6443c5de6bf7e02886256dd7b3cd3c9502a4", "0x0d32c1bd21baf43e72d5d82d461ef54833807ff81a877adc822f27a6db88d754", "0x0fe15e055c0803d5ebe6dd77689b70cfd82138f008810ce24535c992daaff27d", "0x1fba82c012671212ce2fc13fd09bf8fba4f7d5875ab8d37495d1ccfcff287331", "0x090738a5842fa4d2699b3726aa0dd97cb59569b4be2c6825335ec4969f859dc2", "0x0c6cb72dabbc28abcf4a50c203534e066c29f48c24ca64d672092f263df3f9d7", "0x0f27fbea0d9145f815c288b50fe7e8c10b8185d325b5264624fd57102855d05d", "0x2a815cd3fd1c43c72ee0130465250ff771d1e7be2347e4ada331b83265a03450", "0x148b4ecf2ad7ed17409417086867ee27bc1b0906dbc9cbb3714c285071e2db70", "0x08e700a42b1d6d36ee65f8ebedf47d3a44463ff9fa579dce13b7492e20142c3a", "0x2e23c69521d572ff2152c50f8c9a9191535f4cf37f95f1e0428692e78842b642", "0x14519e0354365923fb41400c19866135b45e975d56a0980260bc99f0390b1d5f", "0x04caded1f05738f736cb5bcf08d785e395e58eb7738523a20638aa16bc51593e", "0x28787eaccd38383215ea21ec02895c32d979f68ca155f534a2e2d377bff6698b", "0x20a1b81fa96c58cf11c5762c5ceb731efdcb081fca2d34d5c463d2cf40e6da18", "0x11789a06fe3bf53833741d180f068d29534d5bb58a5c64b8119542e62b189fb4", "0x23d00fcd032ace719ffcbc513bfa177a55b04377d76455c2788d999d05d011e2", "0x01f0e81b57b4a73cc118e51ede18f8724debf25c2d109db6ef45280f99f1a3fa", "0x156d1c9b61749810de728f259c2c1c1fd4dbff97101426e26087ca461c93307c", "0x1c5d619ac3a478cfd06d5eebfd879960bb321236be173813f5e78d1366d32c69", "0x250cfae4e1dfc551406f1f3d10b649a637dcb7bcb0f6f697994cf96afd35d0c1", "0x242b999f58cf5f53c874d1092bd38725aa9ea076f5bc8f176efa9ea23393874b", "0x2e15748255c4a5e0e9fe38047341b692a967257de27a85a3a38681bc9f1602ea", "0x01ef83886ea7017253699cb6371988eb8e21b4f7023d7479ece4907fe6d4a6fd", "0x08db2dbc271e375b9312f695c59c48f313235b3432cad50921c8d9ad6dd7ad7a", "0x199309f2c2cd45c15a4abb0e6554a1615ff5a6e9488a8d900bbf835fc8f664ef", "0x074be7a3d88e31ab1b59c9208c012bcfb1f85f351c709e68134996891db52b57", "0x301b1011354d2ebf46134fc4d6d734bb6ed8542d719f38f5e09a376a580cad7f", "0x12968f3eccaa27e44f14d5aaac6ecb70c00d040e07536292e685d7cab03fc563", "0x2110a023c8c22fd2ed70270a2d0a265b92a32ce2217ffe1be9a5d7d5c25f512f", "0x1e8cf4c60c53900f0430d5b44de5804fe8b38299bc803beeb4216e1a289cf624", "0x12301cb908ccb28a2616e29b831ec7105b5d3ebf45ff5fe91d50a9dd53a50b52", "0x0f1029ed107d84ff2d6d4a416cbd01da3f3d7bf5b2209ce93ba424f4b85616fc", "0x1b431d016611b8abd684afd9e92331c3325967b1116bfa91d4f44e2f8e2c9fc2", "0x281e335a0fd117064c8ace3f01e02b134a19e9b9220571ebfaaaa0e3a12d34db", "0x22559c106f77e2ae95677d5e38e288343e3b7168371aec7d3aaab9ef8150af70", "0x13f113b1d9b590149cf08c3f6e90589cda5c7b98528866b891256cb9d5d814e7", "0x10252ef388e4c80246962e98b9e976fab2cd25e1e6f1e3fd2a7d4786c5218a97", "0x16b890723dfdebd9912a9207255f95cb800222165b6fae97ec46e461f23e83f3", "0x25caf77c7d2e8e069341ec90f3c8f6d64319cfd2d77cab0625cf0377285ba11c", "0x016c84288b0bc3c50eebbe250cdd5a4ee50b2c65a24ac64d0c930cbdecb95141", "0x20a537c045b069d47dc6315f45b391f60681222381e5059ec7c8b17bf677d911", "0x2594c0edfcd4064d215a3d797bc8e3b2f401c61f3961ae96ccbec8f8fd29e81f", "0x1c831d7047483ca00ed59bdb84c47ffb8bbebbae92aa164c7b35fcffbb8a35d3", "0x2ea7f60de52b8cd6b0bd06f861fc1f2c5ed1d1fbfa53caccdb836400a03df434", "0x275c6c8bd115f7d2ce196439e2330fad305c6745bab0bf1ce3f2fa32dadc3c43", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x2b3f4e210619347288731e7f0eea1ae60dd8696fe87319044864d099a03a9536", "0x0fecd3d2aebedeb8be2b0b7e3a74de9ec8bd2cb72851541463729e0715aef48b", "0x10bee385ad0c2cd3ff88ef4d630840749e4367f9add4a300fc4f545a7778e92c", "0x1fe792730eeafbd22c4eb80e86e2b40108b1e55b2a08db786289eea5745b9e3b", "0x04d411679da432816b213cd5580dda1fd6c2f258684c036be19b5b26baca583c", "0x159f17b655d2b8a803e0cfb564918628be52d3baa950ca1b127854491624f8f4", "0x225340463867d9252a1269013536e2e1dd219aa18eadef13c324b63d44679334", "0x1885e231554e02abb40ed54b72ebf09b883d0298a6bc06fc645a30365f370ef2", "0x233344517f25170972b8ba35d01f2df2e073d322993abce7df26796126e93498", "0x08990e8faa13b18b4433ec417c5cc596885e11ffd372d5f612c08cc79a5d5c80", "0x1e960a0c892b755c28e21dcbed816c1b182d7da43bae07f8ee622bd4485f79e7", "0x27b58e2ee290a179d349ace82752528b2ff946d60c092b99ef42f53c25d0c99f", "0x2a5cf8a3193107d982edd253002c7a52ab876b445dde8307ab78fbdca022d93c", "0x2b1ab4d5277f8c82750c1c7bd043889b71465ec64a9afc1bfa37d06b1ebd0725", "0x2a0dbf5c4373a58a83d5f2a031ea0615bf12800e33b70c3191a7cbb15966ced8", "0x1f272bb4a19d14a0abdfebc9fc83125e10623b9aef730f8d25f2bf5bead38ea9", "0x2c2339cf0ae7aff56091a568c1e2c3f01f52d8ed13400737fd31eaabcaffb9bd", "0x21f5fefe6b5fa0b5da71089befb74a1a39e52b4f830cb330c3c284e154614dfd", "0x1e6f6ba4b2444586b380dc4e2b3fad111ff1f4754420a846f53ea0789ebfb0ad", "0x1193d170b0b2dd0c4a04331a4b4aa3f12920f182ec3ab547837e30f1116ca584", "0x00000000000000000000000000000025704a15c9e2ce8a69558e7bbcdcbc7784", "0x2e5d36112770fb6c985681cafe40a8c99ad13f702309e7969801dd0ed080e727", "0x0eefc2585f591bb457183134e19ad643966272234d645514bf7868d6dd8ae2cb", "0x300803e4e2339ad39b9c31f228949bbeaf9c74b7101e7be1930b088126247eaa", "0x2bb562a50ed944b438b83b01f200101a34faef7f296a75c84c731755ebddbc1a", "0x1288e0b9c742af39cbcac21357c1b29511b0bbdd3d0e3cf5e14b2eef68a28ab3", "0x20f089131cc96d86ff1cfb67fa3f51670f4bad30158751b2587354bbec76cdf9", "0x1a26c6d3e633f9bf8434cf755b5f1217dad0d455071a97a7bcf85b824f5cf07a", "0x0d7e9b8a51fccf910ec25bdbd13e70b34bd6ea6f4d629fa744f9cdf5f2beb1cf", "0x0b40f28ce428e64df9cf5a024133fc420f39decf5f6af020cc3211ab298d4631", "0x0ca4f189dde7a55fe829f46681232904f6670249a22e0deb47222bd309523a8a", "0x2c544f2e31143783977645edb2a6bdb39b875053963bfa1a5b3ae9de204a7ebe", "0x00aae4454eb48fb18ff60db6b9d015abea2e770a2f7d86d121522b834c791ba5", "0x07d74e351fd4cccf4e18475d25211efa8a359066fc693a5c8505ddb507e4b74b", "0x07d74e351fd4cccf4e18475d25211efa8a359066fc693a5c8505ddb507e4b74b", "0x2d9e5bff47207d82533e2445959941181cc890c5779bc7f24d6e8a7b9e425b5c", "0x0aea3c0c317c441a5775a9849108d7a6889b39128235f717b09b184aa08e4eb7", "0x1ca5bc6fb37c55a562f4991901c39902f42d14db71284116df74cb4e7d55e493", "0x220fed26d64cd69f40e6d145a423e4a3c8cd0dce747e7d51647441270ad4d774", "0x15be574c9358889257aa2a30ff7b5fcc31a57da7032296e2c1201c49a44bbdb6", "0x2de539925525bedd3b7f43a9c6bf0f713151a17f79ac7ff4a9cd27b15ffe892a", "0x083086693dbf465211741e2cbff70ff38eb08383faf22d397eb2742c8ad7396a", "0x1fdfa258a890598816e807c50058d7a1462edd5ff196a2eae0f862e454b49aa1", "0x10c434c6daaa8226fa8e3e302123dfdc4455cf68063df518949df5a65a945213", "0x0000000000000000000000000000006472a7874de2c454a4591ed7784df1c104", "0x000000000000000000000000000000000008c46ac53d2c4ad0c26a5d6c790082", "0x0000000000000000000000000000005e422f9cfb8725800de60dfe0a8d4104c0", "0x000000000000000000000000000000000000f10fd4e4de81a0c00073ec91c274", "0x000000000000000000000000000000b20813090eca76bc6aa4a699b1ec8d5d6d", "0x0000000000000000000000000000000000292cc9f8a744eb00e0903c29ce87a7", "0x000000000000000000000000000000350a368b415fbb99fa90a26a42b1a3affd", "0x0000000000000000000000000000000000280eb9275cb05a3435f464d1dc369d", "0x000000000000000000000000000000280df6505e20c7725fe6d29439f96ee05d", "0x000000000000000000000000000000000017ef5033a08535451e2747827aa94b", "0x0000000000000000000000000000002f9ba89ae91b4e4a4ff8ccbd0526faad2f", "0x00000000000000000000000000000000001c2013561dafcc02cb03220bdf23c4", "0x000000000000000000000000000000aac102c400f9e5da0321ded4510994434b", "0x00000000000000000000000000000000001ec8ab9cc834b492fde124962f04a1", "0x0000000000000000000000000000000673dbd698da8b8cce450d2a083aba9987", "0x00000000000000000000000000000000000a49e55bb040249cb41c63cea901cd", "0x000000000000000000000000000000133d92af8d76ee0c74a12081ee7b2ef8c4", "0x0000000000000000000000000000000000240f552d1c6cbb007650e4b142e0a5", "0x000000000000000000000000000000e29c6e7d982ec08d51c79d6261c28d742d", "0x000000000000000000000000000000000021baeec04d9be419c923626034e7b3", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x1e940a528b42d8230e7d4dff76262a80986c0d00b2c02a9bc0559e36212d1547", "0x1ceccf21ac39f70d76ad6f7fe0dcb33b6af04555a0b1959e4714d65925e4e253", "0x096139d757046cdbdb7ee89a95f112f70882a43a46c2f739d9be115dda013420", "0x2f9c8ac67c7825b08eff0e7f7656a671f4c64e5601f2efab35b1b795801eec04", "0x2077e648e1704851cdffd7e6e56311634a7b741bab77ca34d9dff12a6a2bfe99", "0x115d48c4a97aeb3c447a060f9e0d675b0dc7f4a05a3f5776e2f279f3a165d7dc", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x000000000000000000000000000000fd38c45c3ec5b841482a80e3a56ce82555", "0x00000000000000000000000000000000000ad70b03f092f60af3e0ce1bb29d2c", "0x0000000000000000000000000000007a184d5342c90c634c0b1a050f0b97c9fb", "0x0000000000000000000000000000000000271f42abcb3bc1f0332e4b3ca85e1d", "0x0000000000000000000000000000008256322bbe2c1b8cd9d84e5ff6123477f2", "0x000000000000000000000000000000000025cab962761681dd9547f4c78814df", "0x0000000000000000000000000000008c4234510e5825c02b9ac427bcbf8e279a", "0x000000000000000000000000000000000013a14e0d7fc073c44643af38cc5396"] -public_inputs = ["0x0000000000000000000000000000000000000000000000000000000000000003"] -verification_key = ["0x0000000000000000000000000000000000000000000000000000000000000040", "0x0000000000000000000000000000000000000000000000000000000000000011", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000003", "0x0000000000000000000000000000000000000000000000000000000000000004", "0x0000000000000000000000000000000000000000000000000000000000000005", "0x0000000000000000000000000000000000000000000000000000000000000006", "0x0000000000000000000000000000000000000000000000000000000000000007", "0x0000000000000000000000000000000000000000000000000000000000000008", "0x0000000000000000000000000000000000000000000000000000000000000009", "0x000000000000000000000000000000000000000000000000000000000000000a", "0x000000000000000000000000000000000000000000000000000000000000000b", "0x000000000000000000000000000000000000000000000000000000000000000c", "0x000000000000000000000000000000000000000000000000000000000000000d", "0x000000000000000000000000000000000000000000000000000000000000000e", "0x000000000000000000000000000000000000000000000000000000000000000f", "0x0000000000000000000000000000000000000000000000000000000000000010", "0x00000000000000000000000000000060e430ad1c23bfcf3514323aae3f206e84", "0x00000000000000000000000000000000001b5c3ff4c2458d8f481b1c068f27ae", "0x000000000000000000000000000000bb510ab2112def34980e4fc6998ad9dd16", "0x00000000000000000000000000000000000576e7c105b43e061e13cb877fefe1", "0x000000000000000000000000000000ced074785d11857b065d8199e6669a601c", "0x00000000000000000000000000000000000053b48a4098c1c0ae268f273952f7", "0x000000000000000000000000000000d1d4b26e941db8168cee8f6de548ae0fd8", "0x00000000000000000000000000000000001a9adf5a6dadc3d948bb61dfd63f4c", "0x0000000000000000000000000000009ce1faac6f8de6ebb18f1db17372c82ad5", "0x00000000000000000000000000000000002002681bb417184b2df070a16a3858", "0x000000000000000000000000000000161baa651a8092e0e84725594de5aba511", "0x00000000000000000000000000000000000be0064399c2a1efff9eb0cdcb2223", "0x0000000000000000000000000000008673be6fd1bdbe980a29d8c1ded54381e7", "0x000000000000000000000000000000000008a5158a7d9648cf1d234524c9fa0c", "0x0000000000000000000000000000002b4fce6e4b1c72062b296d49bca2aa4130", "0x00000000000000000000000000000000002e45a9eff4b6769e55fb710cded44f", "0x00000000000000000000000000000072b85bf733758b76bcf97333efb85a23e3", "0x000000000000000000000000000000000017da0ea508994fc82862715e4b5592", "0x00000000000000000000000000000094fa74695cf058dba8ff35aec95456c6c3", "0x0000000000000000000000000000000000211acddb851061c24b8f159e832bd1", "0x000000000000000000000000000000303b5e5c531384b9a792e11702ad3bcab0", "0x00000000000000000000000000000000000d336dff51a60b8833d5d7f6d4314c", "0x0000000000000000000000000000009f825dde88092070747180d581c342444a", "0x0000000000000000000000000000000000237fbd6511a03cca8cac01b555fe01", "0x0000000000000000000000000000007c313205159495df6d8de292079a4844ff", "0x000000000000000000000000000000000018facdfc468530dd45e8f7a1d38ce9", "0x0000000000000000000000000000000d1ce33446fc3dc4ab40ca38d92dac74e1", "0x00000000000000000000000000000000000852d8e3e0e8f4435af3e94222688b", "0x0000000000000000000000000000006c04ee19ec1dfec87ed47d6d04aa158de2", "0x000000000000000000000000000000000013240f97a584b45184c8ec31319b5f", "0x000000000000000000000000000000cefb5d240b07ceb4be26ea429b6dc9d9e0", "0x00000000000000000000000000000000002dad22022121d689f57fb38ca21349", "0x000000000000000000000000000000c9f189f2a91aeb664ce376d8b157ba98f8", "0x00000000000000000000000000000000002531a51ad54f124d58094b219818d2", "0x000000000000000000000000000000ef1e6db71809307f677677e62b4163f556", "0x0000000000000000000000000000000000272da4396fb2a7ee0638b9140e523d", "0x0000000000000000000000000000002e54c0244a7732c87bc4712a76dd8c83fb", "0x000000000000000000000000000000000007db77b3e04b7eba9643da57cbbe4d", "0x000000000000000000000000000000e0dfe1ddd7f74ae0d636c910c3e85830d8", "0x00000000000000000000000000000000000466fa9b57ec4664abd1505b490862", "0x0000000000000000000000000000009ee55ae8a32fe5384c79907067cc27192e", "0x00000000000000000000000000000000000799d0e465cec07ecb5238c854e830", "0x0000000000000000000000000000001d5910ad361e76e1c241247a823733c39f", "0x00000000000000000000000000000000002b03f2ccf7507564da2e6678bef8fe", "0x000000000000000000000000000000ee40d90bea71fba7a412dd61fcf34e8ceb", "0x0000000000000000000000000000000000140b0936c323fd2471155617b6af56", "0x0000000000000000000000000000002b90071823185c5ff8e440fd3d73b6fefc", "0x00000000000000000000000000000000002b6c10790a5f6631c87d652e059df4", "0x00000000000000000000000000000029a17181c7934fc3fdbd352eac5cb521b9", "0x00000000000000000000000000000000001f497cbf5284ff29a2d336e5991999", "0x000000000000000000000000000000072bd9c0c6beda1fdee6d4ff0432ba9e1b", "0x000000000000000000000000000000000013ea38a0bd2aa751a490a724fac818", "0x000000000000000000000000000000c599f63dcd3edd49f08ae5c3141c1e3493", "0x00000000000000000000000000000000002bdb36be0bea09950dd32a8ccf6fbc", "0x00000000000000000000000000000047f27f29724e7f19eba0340256a0bd4b7d", "0x00000000000000000000000000000000001c1c5ccf87a962129ca785f8f35120", "0x000000000000000000000000000000c5c71efdae00679bbe4a95096e012b1817", "0x000000000000000000000000000000000017a365de041e317817d0135f2b48e0", "0x0000000000000000000000000000008ae711ac402f7848d719c93a89ba8d39f1", "0x00000000000000000000000000000000002b6fb40ed8a1935226f4f9786a0499", "0x0000000000000000000000000000002f03a71501d83de1da5715a4e9462d6198", "0x00000000000000000000000000000000001644064443b8546f48eae693af47b8", "0x00000000000000000000000000000083763ab1b6e8fe269b2fe4c7b9c448c08d", "0x000000000000000000000000000000000021d7cc18c59676a8eeb47c0111c251", "0x000000000000000000000000000000b5f937153073e03ea7d51a996e0ebc2e6b", "0x000000000000000000000000000000000011ddd0e26457373eb06e0493177672", "0x000000000000000000000000000000c5f6eb9f6fc8fa99811a4a88c74a6d018b", "0x000000000000000000000000000000000025bcd07a0732c123567834f5109558", "0x000000000000000000000000000000aeb08a0b1a4442189448b4e97490568146", "0x000000000000000000000000000000000002a1744e4771705536a88f07e0f90f", "0x000000000000000000000000000000b938568293bd0724b0ea76c2ec34c4a829", "0x0000000000000000000000000000000000053296e8f3b9ad3af877dfa9c7c2a7", "0x000000000000000000000000000000f0ca1db6323996eba26bdc86dafef9d10b", "0x00000000000000000000000000000000001441a46c58af03d5645d52721d956a", "0x0000000000000000000000000000008bbf8f884013c66c28ba09c2fbd573b656", "0x0000000000000000000000000000000000206c391ca06fac27d1908e94570243", "0x0000000000000000000000000000002d4f5aaed88ba4f79612d53b804ca8f194", "0x00000000000000000000000000000000001674011c96392df08970fa6b7b4cb8", "0x0000000000000000000000000000009f88297c1729d76c4d9306853598c91325", "0x0000000000000000000000000000000000256f51adfcacc3c1e340be4d32d3e9", "0x0000000000000000000000000000000ab9955eec0d74eb799afed2a802b24d75", "0x00000000000000000000000000000000001fcbe43ea105b30d36ed0b21b03411", "0x000000000000000000000000000000d66b1d5433f1aa5305cd1edce7c22de466", "0x00000000000000000000000000000000002331546a256b8a3b751956806680d4", "0x000000000000000000000000000000e97954ad6cd6f45fb15c91434121db4304", "0x00000000000000000000000000000000002e20a97e09d50f227ced47e7a98250", "0x0000000000000000000000000000001ebbc27eb9ebededefba79522eb58ae89b", "0x0000000000000000000000000000000000090efa4974e566e81d1177b85a30be", "0x0000000000000000000000000000005eafa070b9c9632404052642e3bc14f9fd", "0x00000000000000000000000000000000001489068864102daca6a6b8bc4d448b", "0x0000000000000000000000000000009ebc91aaaac036a6477cadbe54e8556dfd", "0x00000000000000000000000000000000000ef6d835e2ed3343b95c82c8c54037", "0x00000000000000000000000000000033b28b529dff46e93af4e7422530478e4a", "0x000000000000000000000000000000000020a86c2f8591bf190bcddcc03c42fb", "0x000000000000000000000000000000a9679d0acc088f7dc27bf6d866bcd2dda2", "0x00000000000000000000000000000000002fb9d0d2d4099402bed74f738f64cc", "0x00000000000000000000000000000023b09f876a29a061582848a8b9a5870c12", "0x00000000000000000000000000000000001d5bb906f03f0d49e9c4791bc43af9", "0x00000000000000000000000000000017aac9854ea240d8ec97bf760c4d4ba870", "0x00000000000000000000000000000000000b227a556c414ada0dc75bb303e30e", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000009b624fa65d1a24b7f14a8f25f3789622af", "0x000000000000000000000000000000000013d47bff8c630e847b70e2732fd3f0", "0x00000000000000000000000000000061d21663e93132f32921075f4c936a84df", "0x00000000000000000000000000000000001a74ca4e118fb480b9b999902989a3"] -proof_b = ["0x0000000000000000000000000000000000000000000000000000000000000040", "0x0000000000000000000000000000000000000000000000000000000000000011", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000042ab5d6d1986846cf", "0x00000000000000000000000000000000000000000000000b75c020998797da78", "0x0000000000000000000000000000000000000000000000005a107acb64952eca", "0x000000000000000000000000000000000000000000000000000031e97a575e9d", "0x00000000000000000000000000000000000000000000000b5666547acf8bd5a4", "0x00000000000000000000000000000000000000000000000c410db10a01750aeb", "0x00000000000000000000000000000000000000000000000d722669117f9758a4", "0x000000000000000000000000000000000000000000000000000178cbf4206471", "0x000000000000000000000000000000000000000000000000e91b8a11e7842c38", "0x000000000000000000000000000000000000000000000007fd51009034b3357f", "0x000000000000000000000000000000000000000000000009889939f81e9c7402", "0x0000000000000000000000000000000000000000000000000000f94656a2ca48", "0x000000000000000000000000000000000000000000000006fb128b46c1ddb67f", "0x0000000000000000000000000000000000000000000000093fe27776f50224bd", "0x000000000000000000000000000000000000000000000004a0c80c0da527a081", "0x0000000000000000000000000000000000000000000000000001b52c2020d746", "0x0000000000000000000000000000005a9bae947e1e91af9e4033d8d6aa6ed632", "0x000000000000000000000000000000000025e485e013446d4ac7981c88ba6ecc", "0x000000000000000000000000000000ff1e0496e30ab24a63b32b2d1120b76e62", "0x00000000000000000000000000000000001afe0a8a685d7cd85d1010e55d9d7c", "0x000000000000000000000000000000b0804efd6573805f991458295f510a2004", "0x00000000000000000000000000000000000c81a178016e2fe18605022d5a8b0e", "0x000000000000000000000000000000eba51e76eb1cfff60a53a0092a3c3dea47", "0x000000000000000000000000000000000022e7466247b533282f5936ac4e6c15", "0x00000000000000000000000000000071b1d76edf770edff98f00ff4deec264cd", "0x00000000000000000000000000000000001e48128e68794d8861fcbb2986a383", "0x000000000000000000000000000000d3a2af4915ae6d86b097adc377fafda2d4", "0x000000000000000000000000000000000006359de9ca452dab3a4f1f8d9c9d98", "0x0000000000000000000000000000006cf7dd96d7636fda5953191b1ad776d491", "0x00000000000000000000000000000000001633d881a08d136e834cb13a28fcc6", "0x00000000000000000000000000000001254956cff6908b069fca0e6cf1c47eb1", "0x000000000000000000000000000000000006f4d4dd3890e997e75e75886bf8f7", "0x0000000000000000000000000000006cf7dd96d7636fda5953191b1ad776d491", "0x00000000000000000000000000000000001633d881a08d136e834cb13a28fcc6", "0x00000000000000000000000000000001254956cff6908b069fca0e6cf1c47eb1", "0x000000000000000000000000000000000006f4d4dd3890e997e75e75886bf8f7", "0x000000000000000000000000000000f968b227a358a305607f3efc933823d288", "0x00000000000000000000000000000000000eaf8adb390375a76d95e918b65e08", "0x000000000000000000000000000000bb34b4b447aae56f5e24f81c3acd6d547f", "0x00000000000000000000000000000000002175d012746260ebcfe339a91a81e1", "0x00000000000000000000000000000052eebbd1f6f7554e837f60c44000ed14b6", "0x00000000000000000000000000000000001c1c045a3ec94b8801f2272cc0b3f4", "0x0000000000000000000000000000004d2ef74134578f6b431a9df071ffca4292", "0x0000000000000000000000000000000000291326ade7aa6f0dfc8900eab5580b", "0x0000000000000000000000000000002433eec6418a6dba820c9527e2581fc8bc", "0x00000000000000000000000000000000000e88b7daad19af2ac2f9bdf9e50ee2", "0x000000000000000000000000000000dcfce2c427155cc3e4d035735d3dd5ece8", "0x00000000000000000000000000000000002d7d473cac1a15d0fee8b22c1a7b3e", "0x1a4249b90be4602c8ff40c7c276160ee41b2a0f8a238ce7706e9face2db03d48", "0x162204b9d54d3ffd285c393a5a1ff76ee681474fd780a21a3cf7fac5c24fc2b9", "0x30279eb953d8ee79b2155c69c04e6443c5de6bf7e02886256dd7b3cd3c9502a4", "0x0d32c1bd21baf43e72d5d82d461ef54833807ff81a877adc822f27a6db88d754", "0x0fe15e055c0803d5ebe6dd77689b70cfd82138f008810ce24535c992daaff27d", "0x1fba82c012671212ce2fc13fd09bf8fba4f7d5875ab8d37495d1ccfcff287331", "0x090738a5842fa4d2699b3726aa0dd97cb59569b4be2c6825335ec4969f859dc2", "0x0c6cb72dabbc28abcf4a50c203534e066c29f48c24ca64d672092f263df3f9d7", "0x0f27fbea0d9145f815c288b50fe7e8c10b8185d325b5264624fd57102855d05d", "0x2a815cd3fd1c43c72ee0130465250ff771d1e7be2347e4ada331b83265a03450", "0x148b4ecf2ad7ed17409417086867ee27bc1b0906dbc9cbb3714c285071e2db70", "0x08e700a42b1d6d36ee65f8ebedf47d3a44463ff9fa579dce13b7492e20142c3a", "0x2e23c69521d572ff2152c50f8c9a9191535f4cf37f95f1e0428692e78842b642", "0x14519e0354365923fb41400c19866135b45e975d56a0980260bc99f0390b1d5f", "0x04caded1f05738f736cb5bcf08d785e395e58eb7738523a20638aa16bc51593e", "0x28787eaccd38383215ea21ec02895c32d979f68ca155f534a2e2d377bff6698b", "0x20a1b81fa96c58cf11c5762c5ceb731efdcb081fca2d34d5c463d2cf40e6da18", "0x11789a06fe3bf53833741d180f068d29534d5bb58a5c64b8119542e62b189fb4", "0x23d00fcd032ace719ffcbc513bfa177a55b04377d76455c2788d999d05d011e2", "0x01f0e81b57b4a73cc118e51ede18f8724debf25c2d109db6ef45280f99f1a3fa", "0x156d1c9b61749810de728f259c2c1c1fd4dbff97101426e26087ca461c93307c", "0x1c5d619ac3a478cfd06d5eebfd879960bb321236be173813f5e78d1366d32c69", "0x250cfae4e1dfc551406f1f3d10b649a637dcb7bcb0f6f697994cf96afd35d0c1", "0x242b999f58cf5f53c874d1092bd38725aa9ea076f5bc8f176efa9ea23393874b", "0x2e15748255c4a5e0e9fe38047341b692a967257de27a85a3a38681bc9f1602ea", "0x01ef83886ea7017253699cb6371988eb8e21b4f7023d7479ece4907fe6d4a6fd", "0x08db2dbc271e375b9312f695c59c48f313235b3432cad50921c8d9ad6dd7ad7a", "0x199309f2c2cd45c15a4abb0e6554a1615ff5a6e9488a8d900bbf835fc8f664ef", "0x074be7a3d88e31ab1b59c9208c012bcfb1f85f351c709e68134996891db52b57", "0x301b1011354d2ebf46134fc4d6d734bb6ed8542d719f38f5e09a376a580cad7f", "0x12968f3eccaa27e44f14d5aaac6ecb70c00d040e07536292e685d7cab03fc563", "0x2110a023c8c22fd2ed70270a2d0a265b92a32ce2217ffe1be9a5d7d5c25f512f", "0x1e8cf4c60c53900f0430d5b44de5804fe8b38299bc803beeb4216e1a289cf624", "0x12301cb908ccb28a2616e29b831ec7105b5d3ebf45ff5fe91d50a9dd53a50b52", "0x0f1029ed107d84ff2d6d4a416cbd01da3f3d7bf5b2209ce93ba424f4b85616fc", "0x1b431d016611b8abd684afd9e92331c3325967b1116bfa91d4f44e2f8e2c9fc2", "0x281e335a0fd117064c8ace3f01e02b134a19e9b9220571ebfaaaa0e3a12d34db", "0x22559c106f77e2ae95677d5e38e288343e3b7168371aec7d3aaab9ef8150af70", "0x13f113b1d9b590149cf08c3f6e90589cda5c7b98528866b891256cb9d5d814e7", "0x10252ef388e4c80246962e98b9e976fab2cd25e1e6f1e3fd2a7d4786c5218a97", "0x16b890723dfdebd9912a9207255f95cb800222165b6fae97ec46e461f23e83f3", "0x25caf77c7d2e8e069341ec90f3c8f6d64319cfd2d77cab0625cf0377285ba11c", "0x016c84288b0bc3c50eebbe250cdd5a4ee50b2c65a24ac64d0c930cbdecb95141", "0x20a537c045b069d47dc6315f45b391f60681222381e5059ec7c8b17bf677d911", "0x2594c0edfcd4064d215a3d797bc8e3b2f401c61f3961ae96ccbec8f8fd29e81f", "0x1c831d7047483ca00ed59bdb84c47ffb8bbebbae92aa164c7b35fcffbb8a35d3", "0x2ea7f60de52b8cd6b0bd06f861fc1f2c5ed1d1fbfa53caccdb836400a03df434", "0x275c6c8bd115f7d2ce196439e2330fad305c6745bab0bf1ce3f2fa32dadc3c43", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x2b3f4e210619347288731e7f0eea1ae60dd8696fe87319044864d099a03a9536", "0x0fecd3d2aebedeb8be2b0b7e3a74de9ec8bd2cb72851541463729e0715aef48b", "0x10bee385ad0c2cd3ff88ef4d630840749e4367f9add4a300fc4f545a7778e92c", "0x1fe792730eeafbd22c4eb80e86e2b40108b1e55b2a08db786289eea5745b9e3b", "0x04d411679da432816b213cd5580dda1fd6c2f258684c036be19b5b26baca583c", "0x159f17b655d2b8a803e0cfb564918628be52d3baa950ca1b127854491624f8f4", "0x225340463867d9252a1269013536e2e1dd219aa18eadef13c324b63d44679334", "0x1885e231554e02abb40ed54b72ebf09b883d0298a6bc06fc645a30365f370ef2", "0x233344517f25170972b8ba35d01f2df2e073d322993abce7df26796126e93498", "0x08990e8faa13b18b4433ec417c5cc596885e11ffd372d5f612c08cc79a5d5c80", "0x1e960a0c892b755c28e21dcbed816c1b182d7da43bae07f8ee622bd4485f79e7", "0x27b58e2ee290a179d349ace82752528b2ff946d60c092b99ef42f53c25d0c99f", "0x2a5cf8a3193107d982edd253002c7a52ab876b445dde8307ab78fbdca022d93c", "0x2b1ab4d5277f8c82750c1c7bd043889b71465ec64a9afc1bfa37d06b1ebd0725", "0x2a0dbf5c4373a58a83d5f2a031ea0615bf12800e33b70c3191a7cbb15966ced8", "0x1f272bb4a19d14a0abdfebc9fc83125e10623b9aef730f8d25f2bf5bead38ea9", "0x2c2339cf0ae7aff56091a568c1e2c3f01f52d8ed13400737fd31eaabcaffb9bd", "0x21f5fefe6b5fa0b5da71089befb74a1a39e52b4f830cb330c3c284e154614dfd", "0x1e6f6ba4b2444586b380dc4e2b3fad111ff1f4754420a846f53ea0789ebfb0ad", "0x1193d170b0b2dd0c4a04331a4b4aa3f12920f182ec3ab547837e30f1116ca584", "0x00000000000000000000000000000025704a15c9e2ce8a69558e7bbcdcbc7784", "0x2e5d36112770fb6c985681cafe40a8c99ad13f702309e7969801dd0ed080e727", "0x0eefc2585f591bb457183134e19ad643966272234d645514bf7868d6dd8ae2cb", "0x300803e4e2339ad39b9c31f228949bbeaf9c74b7101e7be1930b088126247eaa", "0x2bb562a50ed944b438b83b01f200101a34faef7f296a75c84c731755ebddbc1a", "0x1288e0b9c742af39cbcac21357c1b29511b0bbdd3d0e3cf5e14b2eef68a28ab3", "0x20f089131cc96d86ff1cfb67fa3f51670f4bad30158751b2587354bbec76cdf9", "0x1a26c6d3e633f9bf8434cf755b5f1217dad0d455071a97a7bcf85b824f5cf07a", "0x0d7e9b8a51fccf910ec25bdbd13e70b34bd6ea6f4d629fa744f9cdf5f2beb1cf", "0x0b40f28ce428e64df9cf5a024133fc420f39decf5f6af020cc3211ab298d4631", "0x0ca4f189dde7a55fe829f46681232904f6670249a22e0deb47222bd309523a8a", "0x2c544f2e31143783977645edb2a6bdb39b875053963bfa1a5b3ae9de204a7ebe", "0x00aae4454eb48fb18ff60db6b9d015abea2e770a2f7d86d121522b834c791ba5", "0x07d74e351fd4cccf4e18475d25211efa8a359066fc693a5c8505ddb507e4b74b", "0x07d74e351fd4cccf4e18475d25211efa8a359066fc693a5c8505ddb507e4b74b", "0x2d9e5bff47207d82533e2445959941181cc890c5779bc7f24d6e8a7b9e425b5c", "0x0aea3c0c317c441a5775a9849108d7a6889b39128235f717b09b184aa08e4eb7", "0x1ca5bc6fb37c55a562f4991901c39902f42d14db71284116df74cb4e7d55e493", "0x220fed26d64cd69f40e6d145a423e4a3c8cd0dce747e7d51647441270ad4d774", "0x15be574c9358889257aa2a30ff7b5fcc31a57da7032296e2c1201c49a44bbdb6", "0x2de539925525bedd3b7f43a9c6bf0f713151a17f79ac7ff4a9cd27b15ffe892a", "0x083086693dbf465211741e2cbff70ff38eb08383faf22d397eb2742c8ad7396a", "0x1fdfa258a890598816e807c50058d7a1462edd5ff196a2eae0f862e454b49aa1", "0x10c434c6daaa8226fa8e3e302123dfdc4455cf68063df518949df5a65a945213", "0x0000000000000000000000000000006472a7874de2c454a4591ed7784df1c104", "0x000000000000000000000000000000000008c46ac53d2c4ad0c26a5d6c790082", "0x0000000000000000000000000000005e422f9cfb8725800de60dfe0a8d4104c0", "0x000000000000000000000000000000000000f10fd4e4de81a0c00073ec91c274", "0x000000000000000000000000000000b20813090eca76bc6aa4a699b1ec8d5d6d", "0x0000000000000000000000000000000000292cc9f8a744eb00e0903c29ce87a7", "0x000000000000000000000000000000350a368b415fbb99fa90a26a42b1a3affd", "0x0000000000000000000000000000000000280eb9275cb05a3435f464d1dc369d", "0x000000000000000000000000000000280df6505e20c7725fe6d29439f96ee05d", "0x000000000000000000000000000000000017ef5033a08535451e2747827aa94b", "0x0000000000000000000000000000002f9ba89ae91b4e4a4ff8ccbd0526faad2f", "0x00000000000000000000000000000000001c2013561dafcc02cb03220bdf23c4", "0x000000000000000000000000000000aac102c400f9e5da0321ded4510994434b", "0x00000000000000000000000000000000001ec8ab9cc834b492fde124962f04a1", "0x0000000000000000000000000000000673dbd698da8b8cce450d2a083aba9987", "0x00000000000000000000000000000000000a49e55bb040249cb41c63cea901cd", "0x000000000000000000000000000000133d92af8d76ee0c74a12081ee7b2ef8c4", "0x0000000000000000000000000000000000240f552d1c6cbb007650e4b142e0a5", "0x000000000000000000000000000000e29c6e7d982ec08d51c79d6261c28d742d", "0x000000000000000000000000000000000021baeec04d9be419c923626034e7b3", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x1e940a528b42d8230e7d4dff76262a80986c0d00b2c02a9bc0559e36212d1547", "0x1ceccf21ac39f70d76ad6f7fe0dcb33b6af04555a0b1959e4714d65925e4e253", "0x096139d757046cdbdb7ee89a95f112f70882a43a46c2f739d9be115dda013420", "0x2f9c8ac67c7825b08eff0e7f7656a671f4c64e5601f2efab35b1b795801eec04", "0x2077e648e1704851cdffd7e6e56311634a7b741bab77ca34d9dff12a6a2bfe99", "0x115d48c4a97aeb3c447a060f9e0d675b0dc7f4a05a3f5776e2f279f3a165d7dc", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x000000000000000000000000000000fd38c45c3ec5b841482a80e3a56ce82555", "0x00000000000000000000000000000000000ad70b03f092f60af3e0ce1bb29d2c", "0x0000000000000000000000000000007a184d5342c90c634c0b1a050f0b97c9fb", "0x0000000000000000000000000000000000271f42abcb3bc1f0332e4b3ca85e1d", "0x0000000000000000000000000000008256322bbe2c1b8cd9d84e5ff6123477f2", "0x000000000000000000000000000000000025cab962761681dd9547f4c78814df", "0x0000000000000000000000000000008c4234510e5825c02b9ac427bcbf8e279a", "0x000000000000000000000000000000000013a14e0d7fc073c44643af38cc5396"] \ No newline at end of file diff --git a/noir/noir-repo/test_programs/execution_success/double_verify_honk_proof_recursive/src/main.nr b/noir/noir-repo/test_programs/execution_success/double_verify_honk_proof_recursive/src/main.nr deleted file mode 100644 index 63902824da1..00000000000 --- a/noir/noir-repo/test_programs/execution_success/double_verify_honk_proof_recursive/src/main.nr +++ /dev/null @@ -1,29 +0,0 @@ -// This circuit aggregates two Honk proofs from `assert_statement_recursive`. -global SIZE_OF_PROOF_IF_LOGN_IS_28: u32 = 463; -global HONK_IDENTIFIER: u32 = 1; -#[recursive] -fn main( - verification_key: [Field; 128], - // This is the proof without public inputs attached. - // This means: the size of this does not change with the number of public inputs. - proof: [Field; SIZE_OF_PROOF_IF_LOGN_IS_28], - public_inputs: pub [Field; 1], - key_hash: Field, - // The second proof, currently set to be identical to the first proof - proof_b: [Field; SIZE_OF_PROOF_IF_LOGN_IS_28], -) { - std::verify_proof_with_type( - verification_key, - proof, - public_inputs, - key_hash, - HONK_IDENTIFIER, - ); - std::verify_proof_with_type( - verification_key, - proof_b, - public_inputs, - key_hash, - HONK_IDENTIFIER, - ); -} diff --git a/noir/noir-repo/test_programs/execution_success/higher_order_functions/src/main.nr b/noir/noir-repo/test_programs/execution_success/higher_order_functions/src/main.nr index 6d094946f6c..1f9598f8591 100644 --- a/noir/noir-repo/test_programs/execution_success/higher_order_functions/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/higher_order_functions/src/main.nr @@ -5,7 +5,7 @@ fn main(w: Field) -> pub Field { assert(twice(|x| x * 2, 5) == 20); assert((|x, y| x + y + 1)(2, 3) == 6); // nested lambdas - assert((|a, b| { a + (|c| c + 2)(b) })(0, 1) == 3); + assert((|a, b| a + (|c| c + 2)(b))(0, 1) == 3); // Closures: let a = 42; let g = || a; diff --git a/noir/noir-repo/test_programs/execution_success/verify_honk_proof/Nargo.toml b/noir/noir-repo/test_programs/execution_success/verify_honk_proof/Nargo.toml deleted file mode 100644 index 8fce1bf44b6..00000000000 --- a/noir/noir-repo/test_programs/execution_success/verify_honk_proof/Nargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "verify_honk_proof" -type = "bin" -authors = [""] - -[dependencies] diff --git a/noir/noir-repo/test_programs/execution_success/verify_honk_proof/Prover.toml b/noir/noir-repo/test_programs/execution_success/verify_honk_proof/Prover.toml deleted file mode 100644 index 45a84c26eb8..00000000000 --- a/noir/noir-repo/test_programs/execution_success/verify_honk_proof/Prover.toml +++ /dev/null @@ -1,4 +0,0 @@ -key_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" -proof = ["0x0000000000000000000000000000000000000000000000000000000000000040", "0x0000000000000000000000000000000000000000000000000000000000000011", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000042ab5d6d1986846cf", "0x00000000000000000000000000000000000000000000000b75c020998797da78", "0x0000000000000000000000000000000000000000000000005a107acb64952eca", "0x000000000000000000000000000000000000000000000000000031e97a575e9d", "0x00000000000000000000000000000000000000000000000b5666547acf8bd5a4", "0x00000000000000000000000000000000000000000000000c410db10a01750aeb", "0x00000000000000000000000000000000000000000000000d722669117f9758a4", "0x000000000000000000000000000000000000000000000000000178cbf4206471", "0x000000000000000000000000000000000000000000000000e91b8a11e7842c38", "0x000000000000000000000000000000000000000000000007fd51009034b3357f", "0x000000000000000000000000000000000000000000000009889939f81e9c7402", "0x0000000000000000000000000000000000000000000000000000f94656a2ca48", "0x000000000000000000000000000000000000000000000006fb128b46c1ddb67f", "0x0000000000000000000000000000000000000000000000093fe27776f50224bd", "0x000000000000000000000000000000000000000000000004a0c80c0da527a081", "0x0000000000000000000000000000000000000000000000000001b52c2020d746", "0x0000000000000000000000000000005a9bae947e1e91af9e4033d8d6aa6ed632", "0x000000000000000000000000000000000025e485e013446d4ac7981c88ba6ecc", "0x000000000000000000000000000000ff1e0496e30ab24a63b32b2d1120b76e62", "0x00000000000000000000000000000000001afe0a8a685d7cd85d1010e55d9d7c", "0x000000000000000000000000000000b0804efd6573805f991458295f510a2004", "0x00000000000000000000000000000000000c81a178016e2fe18605022d5a8b0e", "0x000000000000000000000000000000eba51e76eb1cfff60a53a0092a3c3dea47", "0x000000000000000000000000000000000022e7466247b533282f5936ac4e6c15", "0x00000000000000000000000000000071b1d76edf770edff98f00ff4deec264cd", "0x00000000000000000000000000000000001e48128e68794d8861fcbb2986a383", "0x000000000000000000000000000000d3a2af4915ae6d86b097adc377fafda2d4", "0x000000000000000000000000000000000006359de9ca452dab3a4f1f8d9c9d98", "0x0000000000000000000000000000006cf7dd96d7636fda5953191b1ad776d491", "0x00000000000000000000000000000000001633d881a08d136e834cb13a28fcc6", "0x00000000000000000000000000000001254956cff6908b069fca0e6cf1c47eb1", "0x000000000000000000000000000000000006f4d4dd3890e997e75e75886bf8f7", "0x0000000000000000000000000000006cf7dd96d7636fda5953191b1ad776d491", "0x00000000000000000000000000000000001633d881a08d136e834cb13a28fcc6", "0x00000000000000000000000000000001254956cff6908b069fca0e6cf1c47eb1", "0x000000000000000000000000000000000006f4d4dd3890e997e75e75886bf8f7", "0x000000000000000000000000000000f968b227a358a305607f3efc933823d288", "0x00000000000000000000000000000000000eaf8adb390375a76d95e918b65e08", "0x000000000000000000000000000000bb34b4b447aae56f5e24f81c3acd6d547f", "0x00000000000000000000000000000000002175d012746260ebcfe339a91a81e1", "0x00000000000000000000000000000052eebbd1f6f7554e837f60c44000ed14b6", "0x00000000000000000000000000000000001c1c045a3ec94b8801f2272cc0b3f4", "0x0000000000000000000000000000004d2ef74134578f6b431a9df071ffca4292", "0x0000000000000000000000000000000000291326ade7aa6f0dfc8900eab5580b", "0x0000000000000000000000000000002433eec6418a6dba820c9527e2581fc8bc", "0x00000000000000000000000000000000000e88b7daad19af2ac2f9bdf9e50ee2", "0x000000000000000000000000000000dcfce2c427155cc3e4d035735d3dd5ece8", "0x00000000000000000000000000000000002d7d473cac1a15d0fee8b22c1a7b3e", "0x1a4249b90be4602c8ff40c7c276160ee41b2a0f8a238ce7706e9face2db03d48", "0x162204b9d54d3ffd285c393a5a1ff76ee681474fd780a21a3cf7fac5c24fc2b9", "0x30279eb953d8ee79b2155c69c04e6443c5de6bf7e02886256dd7b3cd3c9502a4", "0x0d32c1bd21baf43e72d5d82d461ef54833807ff81a877adc822f27a6db88d754", "0x0fe15e055c0803d5ebe6dd77689b70cfd82138f008810ce24535c992daaff27d", "0x1fba82c012671212ce2fc13fd09bf8fba4f7d5875ab8d37495d1ccfcff287331", "0x090738a5842fa4d2699b3726aa0dd97cb59569b4be2c6825335ec4969f859dc2", "0x0c6cb72dabbc28abcf4a50c203534e066c29f48c24ca64d672092f263df3f9d7", "0x0f27fbea0d9145f815c288b50fe7e8c10b8185d325b5264624fd57102855d05d", "0x2a815cd3fd1c43c72ee0130465250ff771d1e7be2347e4ada331b83265a03450", "0x148b4ecf2ad7ed17409417086867ee27bc1b0906dbc9cbb3714c285071e2db70", "0x08e700a42b1d6d36ee65f8ebedf47d3a44463ff9fa579dce13b7492e20142c3a", "0x2e23c69521d572ff2152c50f8c9a9191535f4cf37f95f1e0428692e78842b642", "0x14519e0354365923fb41400c19866135b45e975d56a0980260bc99f0390b1d5f", "0x04caded1f05738f736cb5bcf08d785e395e58eb7738523a20638aa16bc51593e", "0x28787eaccd38383215ea21ec02895c32d979f68ca155f534a2e2d377bff6698b", "0x20a1b81fa96c58cf11c5762c5ceb731efdcb081fca2d34d5c463d2cf40e6da18", "0x11789a06fe3bf53833741d180f068d29534d5bb58a5c64b8119542e62b189fb4", "0x23d00fcd032ace719ffcbc513bfa177a55b04377d76455c2788d999d05d011e2", "0x01f0e81b57b4a73cc118e51ede18f8724debf25c2d109db6ef45280f99f1a3fa", "0x156d1c9b61749810de728f259c2c1c1fd4dbff97101426e26087ca461c93307c", "0x1c5d619ac3a478cfd06d5eebfd879960bb321236be173813f5e78d1366d32c69", "0x250cfae4e1dfc551406f1f3d10b649a637dcb7bcb0f6f697994cf96afd35d0c1", "0x242b999f58cf5f53c874d1092bd38725aa9ea076f5bc8f176efa9ea23393874b", "0x2e15748255c4a5e0e9fe38047341b692a967257de27a85a3a38681bc9f1602ea", "0x01ef83886ea7017253699cb6371988eb8e21b4f7023d7479ece4907fe6d4a6fd", "0x08db2dbc271e375b9312f695c59c48f313235b3432cad50921c8d9ad6dd7ad7a", "0x199309f2c2cd45c15a4abb0e6554a1615ff5a6e9488a8d900bbf835fc8f664ef", "0x074be7a3d88e31ab1b59c9208c012bcfb1f85f351c709e68134996891db52b57", "0x301b1011354d2ebf46134fc4d6d734bb6ed8542d719f38f5e09a376a580cad7f", "0x12968f3eccaa27e44f14d5aaac6ecb70c00d040e07536292e685d7cab03fc563", "0x2110a023c8c22fd2ed70270a2d0a265b92a32ce2217ffe1be9a5d7d5c25f512f", "0x1e8cf4c60c53900f0430d5b44de5804fe8b38299bc803beeb4216e1a289cf624", "0x12301cb908ccb28a2616e29b831ec7105b5d3ebf45ff5fe91d50a9dd53a50b52", "0x0f1029ed107d84ff2d6d4a416cbd01da3f3d7bf5b2209ce93ba424f4b85616fc", "0x1b431d016611b8abd684afd9e92331c3325967b1116bfa91d4f44e2f8e2c9fc2", "0x281e335a0fd117064c8ace3f01e02b134a19e9b9220571ebfaaaa0e3a12d34db", "0x22559c106f77e2ae95677d5e38e288343e3b7168371aec7d3aaab9ef8150af70", "0x13f113b1d9b590149cf08c3f6e90589cda5c7b98528866b891256cb9d5d814e7", "0x10252ef388e4c80246962e98b9e976fab2cd25e1e6f1e3fd2a7d4786c5218a97", "0x16b890723dfdebd9912a9207255f95cb800222165b6fae97ec46e461f23e83f3", "0x25caf77c7d2e8e069341ec90f3c8f6d64319cfd2d77cab0625cf0377285ba11c", "0x016c84288b0bc3c50eebbe250cdd5a4ee50b2c65a24ac64d0c930cbdecb95141", "0x20a537c045b069d47dc6315f45b391f60681222381e5059ec7c8b17bf677d911", "0x2594c0edfcd4064d215a3d797bc8e3b2f401c61f3961ae96ccbec8f8fd29e81f", "0x1c831d7047483ca00ed59bdb84c47ffb8bbebbae92aa164c7b35fcffbb8a35d3", "0x2ea7f60de52b8cd6b0bd06f861fc1f2c5ed1d1fbfa53caccdb836400a03df434", "0x275c6c8bd115f7d2ce196439e2330fad305c6745bab0bf1ce3f2fa32dadc3c43", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x2b3f4e210619347288731e7f0eea1ae60dd8696fe87319044864d099a03a9536", "0x0fecd3d2aebedeb8be2b0b7e3a74de9ec8bd2cb72851541463729e0715aef48b", "0x10bee385ad0c2cd3ff88ef4d630840749e4367f9add4a300fc4f545a7778e92c", "0x1fe792730eeafbd22c4eb80e86e2b40108b1e55b2a08db786289eea5745b9e3b", "0x04d411679da432816b213cd5580dda1fd6c2f258684c036be19b5b26baca583c", "0x159f17b655d2b8a803e0cfb564918628be52d3baa950ca1b127854491624f8f4", "0x225340463867d9252a1269013536e2e1dd219aa18eadef13c324b63d44679334", "0x1885e231554e02abb40ed54b72ebf09b883d0298a6bc06fc645a30365f370ef2", "0x233344517f25170972b8ba35d01f2df2e073d322993abce7df26796126e93498", "0x08990e8faa13b18b4433ec417c5cc596885e11ffd372d5f612c08cc79a5d5c80", "0x1e960a0c892b755c28e21dcbed816c1b182d7da43bae07f8ee622bd4485f79e7", "0x27b58e2ee290a179d349ace82752528b2ff946d60c092b99ef42f53c25d0c99f", "0x2a5cf8a3193107d982edd253002c7a52ab876b445dde8307ab78fbdca022d93c", "0x2b1ab4d5277f8c82750c1c7bd043889b71465ec64a9afc1bfa37d06b1ebd0725", "0x2a0dbf5c4373a58a83d5f2a031ea0615bf12800e33b70c3191a7cbb15966ced8", "0x1f272bb4a19d14a0abdfebc9fc83125e10623b9aef730f8d25f2bf5bead38ea9", "0x2c2339cf0ae7aff56091a568c1e2c3f01f52d8ed13400737fd31eaabcaffb9bd", "0x21f5fefe6b5fa0b5da71089befb74a1a39e52b4f830cb330c3c284e154614dfd", "0x1e6f6ba4b2444586b380dc4e2b3fad111ff1f4754420a846f53ea0789ebfb0ad", "0x1193d170b0b2dd0c4a04331a4b4aa3f12920f182ec3ab547837e30f1116ca584", "0x00000000000000000000000000000025704a15c9e2ce8a69558e7bbcdcbc7784", "0x2e5d36112770fb6c985681cafe40a8c99ad13f702309e7969801dd0ed080e727", "0x0eefc2585f591bb457183134e19ad643966272234d645514bf7868d6dd8ae2cb", "0x300803e4e2339ad39b9c31f228949bbeaf9c74b7101e7be1930b088126247eaa", "0x2bb562a50ed944b438b83b01f200101a34faef7f296a75c84c731755ebddbc1a", "0x1288e0b9c742af39cbcac21357c1b29511b0bbdd3d0e3cf5e14b2eef68a28ab3", "0x20f089131cc96d86ff1cfb67fa3f51670f4bad30158751b2587354bbec76cdf9", "0x1a26c6d3e633f9bf8434cf755b5f1217dad0d455071a97a7bcf85b824f5cf07a", "0x0d7e9b8a51fccf910ec25bdbd13e70b34bd6ea6f4d629fa744f9cdf5f2beb1cf", "0x0b40f28ce428e64df9cf5a024133fc420f39decf5f6af020cc3211ab298d4631", "0x0ca4f189dde7a55fe829f46681232904f6670249a22e0deb47222bd309523a8a", "0x2c544f2e31143783977645edb2a6bdb39b875053963bfa1a5b3ae9de204a7ebe", "0x00aae4454eb48fb18ff60db6b9d015abea2e770a2f7d86d121522b834c791ba5", "0x07d74e351fd4cccf4e18475d25211efa8a359066fc693a5c8505ddb507e4b74b", "0x07d74e351fd4cccf4e18475d25211efa8a359066fc693a5c8505ddb507e4b74b", "0x2d9e5bff47207d82533e2445959941181cc890c5779bc7f24d6e8a7b9e425b5c", "0x0aea3c0c317c441a5775a9849108d7a6889b39128235f717b09b184aa08e4eb7", "0x1ca5bc6fb37c55a562f4991901c39902f42d14db71284116df74cb4e7d55e493", "0x220fed26d64cd69f40e6d145a423e4a3c8cd0dce747e7d51647441270ad4d774", "0x15be574c9358889257aa2a30ff7b5fcc31a57da7032296e2c1201c49a44bbdb6", "0x2de539925525bedd3b7f43a9c6bf0f713151a17f79ac7ff4a9cd27b15ffe892a", "0x083086693dbf465211741e2cbff70ff38eb08383faf22d397eb2742c8ad7396a", "0x1fdfa258a890598816e807c50058d7a1462edd5ff196a2eae0f862e454b49aa1", "0x10c434c6daaa8226fa8e3e302123dfdc4455cf68063df518949df5a65a945213", "0x0000000000000000000000000000006472a7874de2c454a4591ed7784df1c104", "0x000000000000000000000000000000000008c46ac53d2c4ad0c26a5d6c790082", "0x0000000000000000000000000000005e422f9cfb8725800de60dfe0a8d4104c0", "0x000000000000000000000000000000000000f10fd4e4de81a0c00073ec91c274", "0x000000000000000000000000000000b20813090eca76bc6aa4a699b1ec8d5d6d", "0x0000000000000000000000000000000000292cc9f8a744eb00e0903c29ce87a7", "0x000000000000000000000000000000350a368b415fbb99fa90a26a42b1a3affd", "0x0000000000000000000000000000000000280eb9275cb05a3435f464d1dc369d", "0x000000000000000000000000000000280df6505e20c7725fe6d29439f96ee05d", "0x000000000000000000000000000000000017ef5033a08535451e2747827aa94b", "0x0000000000000000000000000000002f9ba89ae91b4e4a4ff8ccbd0526faad2f", "0x00000000000000000000000000000000001c2013561dafcc02cb03220bdf23c4", "0x000000000000000000000000000000aac102c400f9e5da0321ded4510994434b", "0x00000000000000000000000000000000001ec8ab9cc834b492fde124962f04a1", "0x0000000000000000000000000000000673dbd698da8b8cce450d2a083aba9987", "0x00000000000000000000000000000000000a49e55bb040249cb41c63cea901cd", "0x000000000000000000000000000000133d92af8d76ee0c74a12081ee7b2ef8c4", "0x0000000000000000000000000000000000240f552d1c6cbb007650e4b142e0a5", "0x000000000000000000000000000000e29c6e7d982ec08d51c79d6261c28d742d", "0x000000000000000000000000000000000021baeec04d9be419c923626034e7b3", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x1e940a528b42d8230e7d4dff76262a80986c0d00b2c02a9bc0559e36212d1547", "0x1ceccf21ac39f70d76ad6f7fe0dcb33b6af04555a0b1959e4714d65925e4e253", "0x096139d757046cdbdb7ee89a95f112f70882a43a46c2f739d9be115dda013420", "0x2f9c8ac67c7825b08eff0e7f7656a671f4c64e5601f2efab35b1b795801eec04", "0x2077e648e1704851cdffd7e6e56311634a7b741bab77ca34d9dff12a6a2bfe99", "0x115d48c4a97aeb3c447a060f9e0d675b0dc7f4a05a3f5776e2f279f3a165d7dc", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x000000000000000000000000000000fd38c45c3ec5b841482a80e3a56ce82555", "0x00000000000000000000000000000000000ad70b03f092f60af3e0ce1bb29d2c", "0x0000000000000000000000000000007a184d5342c90c634c0b1a050f0b97c9fb", "0x0000000000000000000000000000000000271f42abcb3bc1f0332e4b3ca85e1d", "0x0000000000000000000000000000008256322bbe2c1b8cd9d84e5ff6123477f2", "0x000000000000000000000000000000000025cab962761681dd9547f4c78814df", "0x0000000000000000000000000000008c4234510e5825c02b9ac427bcbf8e279a", "0x000000000000000000000000000000000013a14e0d7fc073c44643af38cc5396"] -public_inputs = ["0x0000000000000000000000000000000000000000000000000000000000000003"] -verification_key = ["0x0000000000000000000000000000000000000000000000000000000000000040", "0x0000000000000000000000000000000000000000000000000000000000000011", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000003", "0x0000000000000000000000000000000000000000000000000000000000000004", "0x0000000000000000000000000000000000000000000000000000000000000005", "0x0000000000000000000000000000000000000000000000000000000000000006", "0x0000000000000000000000000000000000000000000000000000000000000007", "0x0000000000000000000000000000000000000000000000000000000000000008", "0x0000000000000000000000000000000000000000000000000000000000000009", "0x000000000000000000000000000000000000000000000000000000000000000a", "0x000000000000000000000000000000000000000000000000000000000000000b", "0x000000000000000000000000000000000000000000000000000000000000000c", "0x000000000000000000000000000000000000000000000000000000000000000d", "0x000000000000000000000000000000000000000000000000000000000000000e", "0x000000000000000000000000000000000000000000000000000000000000000f", "0x0000000000000000000000000000000000000000000000000000000000000010", "0x00000000000000000000000000000060e430ad1c23bfcf3514323aae3f206e84", "0x00000000000000000000000000000000001b5c3ff4c2458d8f481b1c068f27ae", "0x000000000000000000000000000000bb510ab2112def34980e4fc6998ad9dd16", "0x00000000000000000000000000000000000576e7c105b43e061e13cb877fefe1", "0x000000000000000000000000000000ced074785d11857b065d8199e6669a601c", "0x00000000000000000000000000000000000053b48a4098c1c0ae268f273952f7", "0x000000000000000000000000000000d1d4b26e941db8168cee8f6de548ae0fd8", "0x00000000000000000000000000000000001a9adf5a6dadc3d948bb61dfd63f4c", "0x0000000000000000000000000000009ce1faac6f8de6ebb18f1db17372c82ad5", "0x00000000000000000000000000000000002002681bb417184b2df070a16a3858", "0x000000000000000000000000000000161baa651a8092e0e84725594de5aba511", "0x00000000000000000000000000000000000be0064399c2a1efff9eb0cdcb2223", "0x0000000000000000000000000000008673be6fd1bdbe980a29d8c1ded54381e7", "0x000000000000000000000000000000000008a5158a7d9648cf1d234524c9fa0c", "0x0000000000000000000000000000002b4fce6e4b1c72062b296d49bca2aa4130", "0x00000000000000000000000000000000002e45a9eff4b6769e55fb710cded44f", "0x00000000000000000000000000000072b85bf733758b76bcf97333efb85a23e3", "0x000000000000000000000000000000000017da0ea508994fc82862715e4b5592", "0x00000000000000000000000000000094fa74695cf058dba8ff35aec95456c6c3", "0x0000000000000000000000000000000000211acddb851061c24b8f159e832bd1", "0x000000000000000000000000000000303b5e5c531384b9a792e11702ad3bcab0", "0x00000000000000000000000000000000000d336dff51a60b8833d5d7f6d4314c", "0x0000000000000000000000000000009f825dde88092070747180d581c342444a", "0x0000000000000000000000000000000000237fbd6511a03cca8cac01b555fe01", "0x0000000000000000000000000000007c313205159495df6d8de292079a4844ff", "0x000000000000000000000000000000000018facdfc468530dd45e8f7a1d38ce9", "0x0000000000000000000000000000000d1ce33446fc3dc4ab40ca38d92dac74e1", "0x00000000000000000000000000000000000852d8e3e0e8f4435af3e94222688b", "0x0000000000000000000000000000006c04ee19ec1dfec87ed47d6d04aa158de2", "0x000000000000000000000000000000000013240f97a584b45184c8ec31319b5f", "0x000000000000000000000000000000cefb5d240b07ceb4be26ea429b6dc9d9e0", "0x00000000000000000000000000000000002dad22022121d689f57fb38ca21349", "0x000000000000000000000000000000c9f189f2a91aeb664ce376d8b157ba98f8", "0x00000000000000000000000000000000002531a51ad54f124d58094b219818d2", "0x000000000000000000000000000000ef1e6db71809307f677677e62b4163f556", "0x0000000000000000000000000000000000272da4396fb2a7ee0638b9140e523d", "0x0000000000000000000000000000002e54c0244a7732c87bc4712a76dd8c83fb", "0x000000000000000000000000000000000007db77b3e04b7eba9643da57cbbe4d", "0x000000000000000000000000000000e0dfe1ddd7f74ae0d636c910c3e85830d8", "0x00000000000000000000000000000000000466fa9b57ec4664abd1505b490862", "0x0000000000000000000000000000009ee55ae8a32fe5384c79907067cc27192e", "0x00000000000000000000000000000000000799d0e465cec07ecb5238c854e830", "0x0000000000000000000000000000001d5910ad361e76e1c241247a823733c39f", "0x00000000000000000000000000000000002b03f2ccf7507564da2e6678bef8fe", "0x000000000000000000000000000000ee40d90bea71fba7a412dd61fcf34e8ceb", "0x0000000000000000000000000000000000140b0936c323fd2471155617b6af56", "0x0000000000000000000000000000002b90071823185c5ff8e440fd3d73b6fefc", "0x00000000000000000000000000000000002b6c10790a5f6631c87d652e059df4", "0x00000000000000000000000000000029a17181c7934fc3fdbd352eac5cb521b9", "0x00000000000000000000000000000000001f497cbf5284ff29a2d336e5991999", "0x000000000000000000000000000000072bd9c0c6beda1fdee6d4ff0432ba9e1b", "0x000000000000000000000000000000000013ea38a0bd2aa751a490a724fac818", "0x000000000000000000000000000000c599f63dcd3edd49f08ae5c3141c1e3493", "0x00000000000000000000000000000000002bdb36be0bea09950dd32a8ccf6fbc", "0x00000000000000000000000000000047f27f29724e7f19eba0340256a0bd4b7d", "0x00000000000000000000000000000000001c1c5ccf87a962129ca785f8f35120", "0x000000000000000000000000000000c5c71efdae00679bbe4a95096e012b1817", "0x000000000000000000000000000000000017a365de041e317817d0135f2b48e0", "0x0000000000000000000000000000008ae711ac402f7848d719c93a89ba8d39f1", "0x00000000000000000000000000000000002b6fb40ed8a1935226f4f9786a0499", "0x0000000000000000000000000000002f03a71501d83de1da5715a4e9462d6198", "0x00000000000000000000000000000000001644064443b8546f48eae693af47b8", "0x00000000000000000000000000000083763ab1b6e8fe269b2fe4c7b9c448c08d", "0x000000000000000000000000000000000021d7cc18c59676a8eeb47c0111c251", "0x000000000000000000000000000000b5f937153073e03ea7d51a996e0ebc2e6b", "0x000000000000000000000000000000000011ddd0e26457373eb06e0493177672", "0x000000000000000000000000000000c5f6eb9f6fc8fa99811a4a88c74a6d018b", "0x000000000000000000000000000000000025bcd07a0732c123567834f5109558", "0x000000000000000000000000000000aeb08a0b1a4442189448b4e97490568146", "0x000000000000000000000000000000000002a1744e4771705536a88f07e0f90f", "0x000000000000000000000000000000b938568293bd0724b0ea76c2ec34c4a829", "0x0000000000000000000000000000000000053296e8f3b9ad3af877dfa9c7c2a7", "0x000000000000000000000000000000f0ca1db6323996eba26bdc86dafef9d10b", "0x00000000000000000000000000000000001441a46c58af03d5645d52721d956a", "0x0000000000000000000000000000008bbf8f884013c66c28ba09c2fbd573b656", "0x0000000000000000000000000000000000206c391ca06fac27d1908e94570243", "0x0000000000000000000000000000002d4f5aaed88ba4f79612d53b804ca8f194", "0x00000000000000000000000000000000001674011c96392df08970fa6b7b4cb8", "0x0000000000000000000000000000009f88297c1729d76c4d9306853598c91325", "0x0000000000000000000000000000000000256f51adfcacc3c1e340be4d32d3e9", "0x0000000000000000000000000000000ab9955eec0d74eb799afed2a802b24d75", "0x00000000000000000000000000000000001fcbe43ea105b30d36ed0b21b03411", "0x000000000000000000000000000000d66b1d5433f1aa5305cd1edce7c22de466", "0x00000000000000000000000000000000002331546a256b8a3b751956806680d4", "0x000000000000000000000000000000e97954ad6cd6f45fb15c91434121db4304", "0x00000000000000000000000000000000002e20a97e09d50f227ced47e7a98250", "0x0000000000000000000000000000001ebbc27eb9ebededefba79522eb58ae89b", "0x0000000000000000000000000000000000090efa4974e566e81d1177b85a30be", "0x0000000000000000000000000000005eafa070b9c9632404052642e3bc14f9fd", "0x00000000000000000000000000000000001489068864102daca6a6b8bc4d448b", "0x0000000000000000000000000000009ebc91aaaac036a6477cadbe54e8556dfd", "0x00000000000000000000000000000000000ef6d835e2ed3343b95c82c8c54037", "0x00000000000000000000000000000033b28b529dff46e93af4e7422530478e4a", "0x000000000000000000000000000000000020a86c2f8591bf190bcddcc03c42fb", "0x000000000000000000000000000000a9679d0acc088f7dc27bf6d866bcd2dda2", "0x00000000000000000000000000000000002fb9d0d2d4099402bed74f738f64cc", "0x00000000000000000000000000000023b09f876a29a061582848a8b9a5870c12", "0x00000000000000000000000000000000001d5bb906f03f0d49e9c4791bc43af9", "0x00000000000000000000000000000017aac9854ea240d8ec97bf760c4d4ba870", "0x00000000000000000000000000000000000b227a556c414ada0dc75bb303e30e", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000009b624fa65d1a24b7f14a8f25f3789622af", "0x000000000000000000000000000000000013d47bff8c630e847b70e2732fd3f0", "0x00000000000000000000000000000061d21663e93132f32921075f4c936a84df", "0x00000000000000000000000000000000001a74ca4e118fb480b9b999902989a3"] diff --git a/noir/noir-repo/test_programs/execution_success/verify_honk_proof/src/main.nr b/noir/noir-repo/test_programs/execution_success/verify_honk_proof/src/main.nr deleted file mode 100644 index 6e96b459b0b..00000000000 --- a/noir/noir-repo/test_programs/execution_success/verify_honk_proof/src/main.nr +++ /dev/null @@ -1,21 +0,0 @@ -// This circuit aggregates a single Honk proof from `assert_statement_recursive`. -global SIZE_OF_PROOF_IF_LOGN_IS_28: u32 = 463; -global HONK_IDENTIFIER: u32 = 1; -fn main( - verification_key: [Field; 128], - // This is the proof without public inputs attached. - // This means: the size of this does not change with the number of public inputs. - proof: [Field; SIZE_OF_PROOF_IF_LOGN_IS_28], - public_inputs: pub [Field; 1], - // This is currently not public. It is fine given that the vk is a part of the circuit definition. - // I believe we want to eventually make it public too though. - key_hash: Field, -) { - std::verify_proof_with_type( - verification_key, - proof, - public_inputs, - key_hash, - HONK_IDENTIFIER, - ); -} diff --git a/noir/noir-repo/tooling/lsp/src/lib.rs b/noir/noir-repo/tooling/lsp/src/lib.rs index 39e14a74007..a85b9d043b9 100644 --- a/noir/noir-repo/tooling/lsp/src/lib.rs +++ b/noir/noir-repo/tooling/lsp/src/lib.rs @@ -67,8 +67,10 @@ mod modules; mod notifications; mod requests; mod solver; +mod tests; mod trait_impl_method_stub_generator; mod types; +mod use_segment_positions; mod utils; mod visibility; diff --git a/noir/noir-repo/tooling/lsp/src/requests/code_action.rs b/noir/noir-repo/tooling/lsp/src/requests/code_action.rs index 9299dc76368..f3e9130e17d 100644 --- a/noir/noir-repo/tooling/lsp/src/requests/code_action.rs +++ b/noir/noir-repo/tooling/lsp/src/requests/code_action.rs @@ -22,7 +22,7 @@ use noirc_frontend::{ ParsedModule, }; -use crate::{utils, LspState}; +use crate::{use_segment_positions::UseSegmentPositions, utils, LspState}; use super::{process_request, to_lsp_location}; @@ -82,6 +82,7 @@ struct CodeActionFinder<'a> { nesting: usize, /// The line where an auto_import must be inserted auto_import_line: usize, + use_segment_positions: UseSegmentPositions, /// Text edits for the "Remove all unused imports" code action unused_imports_text_edits: Vec, code_actions: Vec, @@ -121,6 +122,7 @@ impl<'a> CodeActionFinder<'a> { interner, nesting: 0, auto_import_line: 0, + use_segment_positions: UseSegmentPositions::default(), unused_imports_text_edits: vec![], code_actions: vec![], } @@ -184,10 +186,11 @@ impl<'a> CodeActionFinder<'a> { impl<'a> Visitor for CodeActionFinder<'a> { fn visit_item(&mut self, item: &Item) -> bool { - if let ItemKind::Import(..) = &item.kind { + if let ItemKind::Import(use_tree, _) = &item.kind { if let Some(lsp_location) = to_lsp_location(self.files, self.file, item.span) { self.auto_import_line = (lsp_location.range.end.line + 1) as usize; } + self.use_segment_positions.add(use_tree); } self.includes_span(item.span) diff --git a/noir/noir-repo/tooling/lsp/src/requests/code_action/import_or_qualify.rs b/noir/noir-repo/tooling/lsp/src/requests/code_action/import_or_qualify.rs index bf1fe906be3..a3053f8f304 100644 --- a/noir/noir-repo/tooling/lsp/src/requests/code_action/import_or_qualify.rs +++ b/noir/noir-repo/tooling/lsp/src/requests/code_action/import_or_qualify.rs @@ -1,4 +1,4 @@ -use lsp_types::{Position, Range, TextEdit}; +use lsp_types::TextEdit; use noirc_errors::Location; use noirc_frontend::{ ast::{Ident, Path}, @@ -8,6 +8,9 @@ use noirc_frontend::{ use crate::{ byte_span_to_range, modules::{relative_module_full_path, relative_module_id_path}, + use_segment_positions::{ + use_completion_item_additional_text_edits, UseCompletionItemAdditionTextEditsRequest, + }, }; use super::CodeActionFinder; @@ -82,25 +85,21 @@ impl<'a> CodeActionFinder<'a> { } fn push_import_code_action(&mut self, full_path: &str) { - let line = self.auto_import_line as u32; - let character = (self.nesting * 4) as u32; - let indent = " ".repeat(self.nesting * 4); - let mut newlines = "\n"; - - // If the line we are inserting into is not an empty line, insert an extra line to make some room - if let Some(line_text) = self.lines.get(line as usize) { - if !line_text.trim().is_empty() { - newlines = "\n\n"; - } - } - let title = format!("Import {}", full_path); - let text_edit = TextEdit { - range: Range { start: Position { line, character }, end: Position { line, character } }, - new_text: format!("use {};{}{}", full_path, newlines, indent), - }; - let code_action = self.new_quick_fix(title, text_edit); + let text_edits = use_completion_item_additional_text_edits( + UseCompletionItemAdditionTextEditsRequest { + full_path, + files: self.files, + file: self.file, + lines: &self.lines, + nesting: self.nesting, + auto_import_line: self.auto_import_line, + }, + &self.use_segment_positions, + ); + + let code_action = self.new_quick_fix_multiple_edits(title, text_edits); self.code_actions.push(code_action); } @@ -238,4 +237,31 @@ fn main() { assert_code_action(title, src, expected).await; } + + #[test] + async fn test_import_code_action_for_struct_inserts_into_existing_use() { + let title = "Import foo::bar::SomeTypeInBar"; + + let src = r#"use foo::bar::SomeOtherType; + +mod foo { + mod bar { + pub struct SomeTypeInBar {} + } +} + +fn foo(x: SomeType>||<", ""), &text_edits[0]); + let result = apply_text_edits(&src.replace(">|<", ""), text_edits); if result != expected { println!("Expected:\n```\n{}\n```\n\nGot:\n```\n{}\n```", expected, result); assert_eq!(result, expected); } } - -fn apply_text_edit(src: &str, text_edit: &TextEdit) -> String { - let mut lines: Vec<_> = src.lines().collect(); - assert_eq!(text_edit.range.start.line, text_edit.range.end.line); - - let mut line = lines[text_edit.range.start.line as usize].to_string(); - line.replace_range( - text_edit.range.start.character as usize..text_edit.range.end.character as usize, - &text_edit.new_text, - ); - lines[text_edit.range.start.line as usize] = &line; - lines.join("\n") -} diff --git a/noir/noir-repo/tooling/lsp/src/requests/completion.rs b/noir/noir-repo/tooling/lsp/src/requests/completion.rs index 658033fc526..b69b261c9c6 100644 --- a/noir/noir-repo/tooling/lsp/src/requests/completion.rs +++ b/noir/noir-repo/tooling/lsp/src/requests/completion.rs @@ -38,7 +38,7 @@ use sort_text::underscore_sort_text; use crate::{ requests::to_lsp_location, trait_impl_method_stub_generator::TraitImplMethodStubGenerator, - utils, visibility::is_visible, LspState, + use_segment_positions::UseSegmentPositions, utils, visibility::is_visible, LspState, }; use super::process_request; @@ -115,6 +115,7 @@ struct NodeFinder<'a> { nesting: usize, /// The line where an auto_import must be inserted auto_import_line: usize, + use_segment_positions: UseSegmentPositions, self_type: Option, in_comptime: bool, } @@ -159,6 +160,7 @@ impl<'a> NodeFinder<'a> { suggested_module_def_ids: HashSet::new(), nesting: 0, auto_import_line: 0, + use_segment_positions: UseSegmentPositions::default(), self_type: None, in_comptime: false, } @@ -1035,6 +1037,8 @@ impl<'a> NodeFinder<'a> { } } + /// Determine where each segment in a `use` statement is located. + fn includes_span(&self, span: Span) -> bool { span.start() as usize <= self.byte_index && self.byte_index <= span.end() as usize } @@ -1042,10 +1046,11 @@ impl<'a> NodeFinder<'a> { impl<'a> Visitor for NodeFinder<'a> { fn visit_item(&mut self, item: &Item) -> bool { - if let ItemKind::Import(..) = &item.kind { + if let ItemKind::Import(use_tree, _) = &item.kind { if let Some(lsp_location) = to_lsp_location(self.files, self.file, item.span) { self.auto_import_line = (lsp_location.range.end.line + 1) as usize; } + self.use_segment_positions.add(use_tree); } self.includes_span(item.span) diff --git a/noir/noir-repo/tooling/lsp/src/requests/completion/auto_import.rs b/noir/noir-repo/tooling/lsp/src/requests/completion/auto_import.rs index e2dd582f2f3..9ed633289c1 100644 --- a/noir/noir-repo/tooling/lsp/src/requests/completion/auto_import.rs +++ b/noir/noir-repo/tooling/lsp/src/requests/completion/auto_import.rs @@ -1,7 +1,11 @@ -use lsp_types::{Position, Range, TextEdit}; use noirc_frontend::hir::def_map::ModuleDefId; -use crate::modules::{relative_module_full_path, relative_module_id_path}; +use crate::{ + modules::{relative_module_full_path, relative_module_id_path}, + use_segment_positions::{ + use_completion_item_additional_text_edits, UseCompletionItemAdditionTextEditsRequest, + }, +}; use super::{ kinds::{FunctionCompletionKind, FunctionKind, RequestedItems}, @@ -76,27 +80,18 @@ impl<'a> NodeFinder<'a> { let mut label_details = completion_item.label_details.unwrap(); label_details.detail = Some(format!("(use {})", full_path)); completion_item.label_details = Some(label_details); - - let line = self.auto_import_line as u32; - let character = (self.nesting * 4) as u32; - let indent = " ".repeat(self.nesting * 4); - let mut newlines = "\n"; - - // If the line we are inserting into is not an empty line, insert an extra line to make some room - if let Some(line_text) = self.lines.get(line as usize) { - if !line_text.trim().is_empty() { - newlines = "\n\n"; - } - } - - completion_item.additional_text_edits = Some(vec![TextEdit { - range: Range { - start: Position { line, character }, - end: Position { line, character }, - }, - new_text: format!("use {};{}{}", full_path, newlines, indent), - }]); - + completion_item.additional_text_edits = + Some(use_completion_item_additional_text_edits( + UseCompletionItemAdditionTextEditsRequest { + full_path: &full_path, + files: self.files, + file: self.file, + lines: &self.lines, + nesting: self.nesting, + auto_import_line: self.auto_import_line, + }, + &self.use_segment_positions, + )); completion_item.sort_text = Some(auto_import_sort_text()); self.completion_items.push(completion_item); diff --git a/noir/noir-repo/tooling/lsp/src/requests/completion/tests.rs b/noir/noir-repo/tooling/lsp/src/requests/completion/tests.rs index 668255eb34d..be3a75f72c8 100644 --- a/noir/noir-repo/tooling/lsp/src/requests/completion/tests.rs +++ b/noir/noir-repo/tooling/lsp/src/requests/completion/tests.rs @@ -15,12 +15,13 @@ mod completion_tests { on_completion_request, }, test_utils, + tests::apply_text_edits, }; use lsp_types::{ CompletionItem, CompletionItemKind, CompletionItemLabelDetails, CompletionParams, - CompletionResponse, DidOpenTextDocumentParams, PartialResultParams, Position, Range, - TextDocumentIdentifier, TextDocumentItem, TextDocumentPositionParams, TextEdit, + CompletionResponse, DidOpenTextDocumentParams, PartialResultParams, Position, + TextDocumentIdentifier, TextDocumentItem, TextDocumentPositionParams, WorkDoneProgressParams, }; use tokio::test; @@ -1392,29 +1393,50 @@ mod completion_tests { #[test] async fn test_auto_imports() { - let src = r#" - mod foo { - mod bar { - pub fn hello_world() {} + let src = r#"mod foo { + mod bar { + pub fn hello_world() {} - struct Foo { - } + struct Foo { + } - impl Foo { - // This is here to make sure it's not offered for completion - fn hello_world() {} - } - } - } + impl Foo { + // This is here to make sure it's not offered for completion + fn hello_world() {} + } + } +} - fn main() { - hel>|< - } +fn main() { + hel>|< +} "#; - let items = get_completions(src).await; + + let expected = r#"use foo::bar::hello_world; + +mod foo { + mod bar { + pub fn hello_world() {} + + struct Foo { + } + + impl Foo { + // This is here to make sure it's not offered for completion + fn hello_world() {} + } + } +} + +fn main() { + hel +} + "#; + + let mut items = get_completions(src).await; assert_eq!(items.len(), 1); - let item = &items[0]; + let item = items.remove(0); assert_eq!(item.label, "hello_world()"); assert_eq!( item.label_details, @@ -1424,38 +1446,43 @@ mod completion_tests { }) ); - assert_eq!( - item.additional_text_edits, - Some(vec![TextEdit { - range: Range { - start: Position { line: 0, character: 0 }, - end: Position { line: 0, character: 0 }, - }, - new_text: "use foo::bar::hello_world;\n".to_string(), - }]) - ); - + let changed = + apply_text_edits(&src.replace(">|<", ""), &item.additional_text_edits.unwrap()); + assert_eq!(changed, expected); assert_eq!(item.sort_text, Some(auto_import_sort_text())); } #[test] async fn test_auto_imports_when_in_nested_module_and_item_is_further_nested() { - let src = r#" - #[something] - mod foo { - mod bar { - pub fn hello_world() {} - } + let src = r#"#[something] +mod foo { + mod bar { + pub fn hello_world() {} + } - fn foo() { - hel>|< - } - } + fn foo() { + hel>|< + } +} "#; - let items = get_completions(src).await; + + let expected = r#"#[something] +mod foo { + use bar::hello_world; + + mod bar { + pub fn hello_world() {} + } + + fn foo() { + hel + } +} + "#; + let mut items = get_completions(src).await; assert_eq!(items.len(), 1); - let item = &items[0]; + let item = items.remove(0); assert_eq!(item.label, "hello_world()"); assert_eq!( item.label_details, @@ -1465,37 +1492,42 @@ mod completion_tests { }) ); - assert_eq!( - item.additional_text_edits, - Some(vec![TextEdit { - range: Range { - start: Position { line: 3, character: 4 }, - end: Position { line: 3, character: 4 }, - }, - new_text: "use bar::hello_world;\n\n ".to_string(), - }]) - ); + let changed = + apply_text_edits(&src.replace(">|<", ""), &item.additional_text_edits.unwrap()); + assert_eq!(changed, expected); } #[test] async fn test_auto_imports_when_in_nested_module_and_item_is_not_further_nested() { - let src = r#" - mod foo { - mod bar { - pub fn hello_world() {} - } + let src = r#"mod foo { + mod bar { + pub fn hello_world() {} + } - mod baz { - fn foo() { - hel>|< - } - } - } - "#; - let items = get_completions(src).await; + mod baz { + fn foo() { + hel>|< + } + } +}"#; + + let expected = r#"mod foo { + mod bar { + pub fn hello_world() {} + } + + mod baz { + use super::bar::hello_world; + + fn foo() { + hel + } + } +}"#; + let mut items = get_completions(src).await; assert_eq!(items.len(), 1); - let item = &items[0]; + let item = items.remove(0); assert_eq!(item.label, "hello_world()"); assert_eq!( item.label_details, @@ -1505,47 +1537,53 @@ mod completion_tests { }) ); - assert_eq!( - item.additional_text_edits, - Some(vec![TextEdit { - range: Range { - start: Position { line: 7, character: 8 }, - end: Position { line: 7, character: 8 }, - }, - new_text: "use super::bar::hello_world;\n\n ".to_string(), - }]) - ); + let changed = + apply_text_edits(&src.replace(">|<", ""), &item.additional_text_edits.unwrap()); + assert_eq!(changed, expected); } #[test] async fn test_auto_import_inserts_after_last_use() { - let src = r#" - mod foo { - mod bar { - pub fn hello_world() {} - } - } + let src = r#"mod foo { + mod bar { + pub fn hello_world() {} + } +} - use foo::bar; +mod baz { + fn qux() {} +} - fn main() { - hel>|< - } - "#; - let items = get_completions(src).await; +use baz::qux; + +fn main() { + hel>|< +}"#; + + let expected = r#"mod foo { + mod bar { + pub fn hello_world() {} + } +} + +mod baz { + fn qux() {} +} + +use baz::qux; +use foo::bar::hello_world; + +fn main() { + hel +}"#; + let mut items = get_completions(src).await; assert_eq!(items.len(), 1); - let item = &items[0]; - assert_eq!( - item.additional_text_edits, - Some(vec![TextEdit { - range: Range { - start: Position { line: 8, character: 0 }, - end: Position { line: 8, character: 0 }, - }, - new_text: "use foo::bar::hello_world;\n".to_string(), - }]) - ); + let item = items.remove(0); + + let changed = + apply_text_edits(&src.replace(">|<", ""), &item.additional_text_edits.unwrap()); + assert_eq!(changed, expected); } #[test] @@ -1589,22 +1627,36 @@ mod completion_tests { #[test] async fn test_auto_import_suggests_modules_too() { - let src = r#" - mod foo { - pub mod barbaz { - fn hello_world() {} - } - } + let src = r#"mod foo { + pub mod barbaz { + fn hello_world() {} + } + } - fn main() { - barb>|< - } - "#; - let items = get_completions(src).await; + fn main() { + barb>|< + } +}"#; + + let expected = r#"use foo::barbaz; + +mod foo { + pub mod barbaz { + fn hello_world() {} + } + } + + fn main() { + barb + } +}"#; + + let mut items = get_completions(src).await; assert_eq!(items.len(), 1); - let item = &items[0]; + let item = items.remove(0); assert_eq!(item.label, "barbaz"); + assert_eq!( item.label_details, Some(CompletionItemLabelDetails { @@ -1612,6 +1664,286 @@ mod completion_tests { description: None }) ); + + let changed = + apply_text_edits(&src.replace(">|<", ""), &item.additional_text_edits.unwrap()); + assert_eq!(changed, expected); + } + + #[test] + async fn test_auto_imports_expands_existing_use_before_one_segment_not_in_list() { + let src = r#"use foo::bar::one_hello_world; + +mod foo { + mod bar { + pub fn one_hello_world() {} + pub fn two_hello_world() {} + } +} + +fn main() { + two_hello_>|< +}"#; + + let expected = r#"use foo::bar::{one_hello_world, two_hello_world}; + +mod foo { + mod bar { + pub fn one_hello_world() {} + pub fn two_hello_world() {} + } +} + +fn main() { + two_hello_ +}"#; + + let mut items = get_completions(src).await; + assert_eq!(items.len(), 1); + + let item = items.remove(0); + let changed = + apply_text_edits(&src.replace(">|<", ""), &item.additional_text_edits.unwrap()); + assert_eq!(changed, expected); + assert_eq!(item.sort_text, Some(auto_import_sort_text())); + } + + #[test] + async fn test_auto_imports_expands_existing_use_before_two_segments() { + let src = r#"use foo::bar::one_hello_world; + +mod foo { + mod bar { + pub fn one_hello_world() {} + } + pub fn two_hello_world() {} +} + +fn main() { + two_hello_>|< +}"#; + + let expected = r#"use foo::{bar::one_hello_world, two_hello_world}; + +mod foo { + mod bar { + pub fn one_hello_world() {} + } + pub fn two_hello_world() {} +} + +fn main() { + two_hello_ +}"#; + + let mut items = get_completions(src).await; + assert_eq!(items.len(), 1); + + let item = items.remove(0); + let changed = + apply_text_edits(&src.replace(">|<", ""), &item.additional_text_edits.unwrap()); + assert_eq!(changed, expected); + assert_eq!(item.sort_text, Some(auto_import_sort_text())); + } + + #[test] + async fn test_auto_imports_expands_existing_use_before_one_segment_inside_list() { + let src = r#"use foo::{bar::one_hello_world, baz}; + +mod foo { + mod bar { + pub fn one_hello_world() {} + pub fn two_hello_world() {} + } + mod baz {} +} + +fn main() { + two_hello_>|< +}"#; + + let expected = r#"use foo::{bar::{one_hello_world, two_hello_world}, baz}; + +mod foo { + mod bar { + pub fn one_hello_world() {} + pub fn two_hello_world() {} + } + mod baz {} +} + +fn main() { + two_hello_ +}"#; + + let mut items = get_completions(src).await; + assert_eq!(items.len(), 1); + + let item = items.remove(0); + let changed = + apply_text_edits(&src.replace(">|<", ""), &item.additional_text_edits.unwrap()); + assert_eq!(changed, expected); + assert_eq!(item.sort_text, Some(auto_import_sort_text())); + } + + #[test] + async fn test_auto_imports_expands_existing_use_before_one_segment_checks_parents() { + let src = r#"use foo::bar::baz; + +mod foo { + mod bar { + mod baz { + pub fn one_hello_world() {} + } + mod qux { + pub fn two_hello_world() {} + } + } +} + +fn main() { + two_hello_>|< +}"#; + + let expected = r#"use foo::bar::{baz, qux::two_hello_world}; + +mod foo { + mod bar { + mod baz { + pub fn one_hello_world() {} + } + mod qux { + pub fn two_hello_world() {} + } + } +} + +fn main() { + two_hello_ +}"#; + + let mut items = get_completions(src).await; + assert_eq!(items.len(), 1); + + let item = items.remove(0); + let changed = + apply_text_edits(&src.replace(">|<", ""), &item.additional_text_edits.unwrap()); + assert_eq!(changed, expected); + assert_eq!(item.sort_text, Some(auto_import_sort_text())); + } + + #[test] + async fn test_auto_imports_expands_existing_use_last_segment() { + let src = r#"use foo::bar; + +mod foo { + mod bar { + pub fn one_hello_world() {} + pub fn two_hello_world() {} + } +} + +fn main() { + two_hello_>|< +}"#; + + let expected = r#"use foo::bar::{self, two_hello_world}; + +mod foo { + mod bar { + pub fn one_hello_world() {} + pub fn two_hello_world() {} + } +} + +fn main() { + two_hello_ +}"#; + + let mut items = get_completions(src).await; + assert_eq!(items.len(), 1); + + let item = items.remove(0); + let changed = + apply_text_edits(&src.replace(">|<", ""), &item.additional_text_edits.unwrap()); + assert_eq!(changed, expected); + assert_eq!(item.sort_text, Some(auto_import_sort_text())); + } + + #[test] + async fn test_auto_imports_expands_existing_use_before_list() { + let src = r#"use foo::bar::{one_hello_world, three_hello_world}; + +mod foo { + mod bar { + pub fn one_hello_world() {} + pub fn two_hello_world() {} + pub fn three_hello_world() {} + } +} + +fn main() { + two_hello_>|< +}"#; + + let expected = r#"use foo::bar::{two_hello_world, one_hello_world, three_hello_world}; + +mod foo { + mod bar { + pub fn one_hello_world() {} + pub fn two_hello_world() {} + pub fn three_hello_world() {} + } +} + +fn main() { + two_hello_ +}"#; + + let mut items = get_completions(src).await; + assert_eq!(items.len(), 1); + + let item = items.remove(0); + let changed = + apply_text_edits(&src.replace(">|<", ""), &item.additional_text_edits.unwrap()); + assert_eq!(changed, expected); + assert_eq!(item.sort_text, Some(auto_import_sort_text())); + } + + #[test] + async fn test_auto_imports_expands_existing_use_before_empty_list() { + let src = r#"use foo::bar::{}; + +mod foo { + mod bar { + pub fn two_hello_world() {} + } +} + +fn main() { + two_hello_>|< +}"#; + + let expected = r#"use foo::bar::{two_hello_world}; + +mod foo { + mod bar { + pub fn two_hello_world() {} + } +} + +fn main() { + two_hello_ +}"#; + + let mut items = get_completions(src).await; + assert_eq!(items.len(), 1); + + let item = items.remove(0); + let changed = + apply_text_edits(&src.replace(">|<", ""), &item.additional_text_edits.unwrap()); + assert_eq!(changed, expected); + assert_eq!(item.sort_text, Some(auto_import_sort_text())); } #[test] diff --git a/noir/noir-repo/tooling/lsp/src/requests/mod.rs b/noir/noir-repo/tooling/lsp/src/requests/mod.rs index 597d8355468..0ee66f1f618 100644 --- a/noir/noir-repo/tooling/lsp/src/requests/mod.rs +++ b/noir/noir-repo/tooling/lsp/src/requests/mod.rs @@ -378,7 +378,7 @@ fn character_to_line_offset(line: &str, character: u32) -> Result } } -fn to_lsp_location<'a, F>( +pub(crate) fn to_lsp_location<'a, F>( files: &'a F, file_id: F::FileId, definition_span: noirc_errors::Span, diff --git a/noir/noir-repo/tooling/lsp/src/tests.rs b/noir/noir-repo/tooling/lsp/src/tests.rs new file mode 100644 index 00000000000..7f2d48cd23f --- /dev/null +++ b/noir/noir-repo/tooling/lsp/src/tests.rs @@ -0,0 +1,33 @@ +#![cfg(test)] + +use lsp_types::TextEdit; + +pub(crate) fn apply_text_edit(src: &str, text_edit: &TextEdit) -> String { + let mut lines: Vec<_> = src.lines().collect(); + assert_eq!(text_edit.range.start.line, text_edit.range.end.line); + + let mut line = lines[text_edit.range.start.line as usize].to_string(); + line.replace_range( + text_edit.range.start.character as usize..text_edit.range.end.character as usize, + &text_edit.new_text, + ); + lines[text_edit.range.start.line as usize] = &line; + lines.join("\n") +} + +pub(crate) fn apply_text_edits(src: &str, text_edits: &[TextEdit]) -> String { + let mut text = src.to_string(); + + // Text edits must be applied from last to first, otherwise if we apply a text edit + // that comes before another one, that other one becomes invalid (it will edit the wrong + // piece of code). + let mut text_edits = text_edits.to_vec(); + text_edits.sort_by_key(|edit| (edit.range.start.line, edit.range.start.character)); + text_edits.reverse(); + + for text_edit in text_edits { + text = apply_text_edit(&text, &text_edit); + } + + text +} diff --git a/noir/noir-repo/tooling/lsp/src/use_segment_positions.rs b/noir/noir-repo/tooling/lsp/src/use_segment_positions.rs new file mode 100644 index 00000000000..f9a3f429029 --- /dev/null +++ b/noir/noir-repo/tooling/lsp/src/use_segment_positions.rs @@ -0,0 +1,336 @@ +use std::collections::HashMap; + +use fm::{FileId, FileMap}; +use lsp_types::{Position, Range, TextEdit}; +use noirc_errors::Span; +use noirc_frontend::ast::{PathKind, UseTree, UseTreeKind}; + +use crate::requests::to_lsp_location; + +/// The position of a segment in a `use` statement. +/// We use this to determine how an auto-import should be inserted. +#[derive(Debug, Default, Copy, Clone)] +pub(crate) enum UseSegmentPosition { + /// The segment either doesn't exist in the source code or there are multiple segments. + /// In this case auto-import will add a new use statement. + #[default] + NoneOrMultiple, + /// The segment is the last one in the `use` statement (or nested use statement): + /// + /// use foo::bar; + /// ^^^ + /// + /// Auto-import will transform it to this: + /// + /// use foo::bar::{self, baz}; + Last { span: Span }, + /// The segment happens before another simple (ident) segment: + /// + /// use foo::bar::qux; + /// ^^^ + /// + /// Auto-import will transform it to this: + /// + /// use foo::bar::{qux, baz}; + BeforeSegment { segment_span_until_end: Span }, + /// The segment happens before a list: + /// + /// use foo::bar::{qux, another}; + /// + /// Auto-import will transform it to this: + /// + /// use foo::bar::{qux, another, baz}; + BeforeList { first_entry_span: Span, list_is_empty: bool }, +} + +/// Remembers where each segment in a `use` statement is located. +/// The key is the full segment, so for `use foo::bar::baz` we'll have three +/// segments: `foo`, `foo::bar` and `foo::bar::baz`, where the span is just +/// for the last identifier (`foo`, `bar` and `baz` in the previous example). +#[derive(Default)] +pub(crate) struct UseSegmentPositions { + use_segment_positions: HashMap, +} + +impl UseSegmentPositions { + pub(crate) fn add(&mut self, use_tree: &UseTree) { + self.gather_use_tree_segments(use_tree, String::new()); + } + + /// Given a full path like `foo::bar::baz`, returns the first non-"NoneOrMultiple" segment position + /// trying each successive parent, together with the name after the parent. + /// + /// For example, first we'll check if `foo::bar` has a single position. If not, we'll try with `foo`. + pub(crate) fn get(&self, full_path: &str) -> (UseSegmentPosition, String) { + // Build a parent path to know in which full segment we need to add this import + let mut segments: Vec<_> = full_path.split("::").collect(); + let mut name = segments.pop().unwrap().to_string(); + let mut parent_path = segments.join("::"); + + loop { + let use_segment_position = + self.use_segment_positions.get(&parent_path).cloned().unwrap_or_default(); + + if let UseSegmentPosition::NoneOrMultiple = use_segment_position { + if let Some(next_name) = segments.pop() { + name = format!("{next_name}::{name}"); + parent_path = segments.join("::"); + } else { + return (UseSegmentPosition::NoneOrMultiple, String::new()); + } + } else { + return (use_segment_position, name); + } + } + } + + fn gather_use_tree_segments(&mut self, use_tree: &UseTree, mut prefix: String) { + let kind_string = match use_tree.prefix.kind { + PathKind::Crate => Some("crate".to_string()), + PathKind::Super => Some("super".to_string()), + PathKind::Dep | PathKind::Plain => None, + }; + if let Some(kind_string) = kind_string { + if let Some(segment) = use_tree.prefix.segments.first() { + self.insert_use_segment_position( + kind_string, + UseSegmentPosition::BeforeSegment { + segment_span_until_end: Span::from( + segment.ident.span().start()..use_tree.span.end() - 1, + ), + }, + ); + } else { + self.insert_use_segment_position_before_use_tree_kind(use_tree, kind_string); + } + } + + let prefix_segments_len = use_tree.prefix.segments.len(); + for (index, segment) in use_tree.prefix.segments.iter().enumerate() { + let ident = &segment.ident; + if !prefix.is_empty() { + prefix.push_str("::"); + }; + prefix.push_str(&ident.0.contents); + + if index < prefix_segments_len - 1 { + self.insert_use_segment_position( + prefix.clone(), + UseSegmentPosition::BeforeSegment { + segment_span_until_end: Span::from( + use_tree.prefix.segments[index + 1].ident.span().start() + ..use_tree.span.end() - 1, + ), + }, + ); + } else { + self.insert_use_segment_position_before_use_tree_kind(use_tree, prefix.clone()); + } + } + + match &use_tree.kind { + UseTreeKind::Path(ident, alias) => { + if !prefix.is_empty() { + prefix.push_str("::"); + } + prefix.push_str(&ident.0.contents); + + if alias.is_none() { + self.insert_use_segment_position( + prefix, + UseSegmentPosition::Last { span: ident.span() }, + ); + } else { + self.insert_use_segment_position(prefix, UseSegmentPosition::NoneOrMultiple); + } + } + UseTreeKind::List(use_trees) => { + for use_tree in use_trees { + self.gather_use_tree_segments(use_tree, prefix.clone()); + } + } + } + } + + fn insert_use_segment_position_before_use_tree_kind( + &mut self, + use_tree: &UseTree, + prefix: String, + ) { + match &use_tree.kind { + UseTreeKind::Path(ident, _alias) => { + self.insert_use_segment_position( + prefix, + UseSegmentPosition::BeforeSegment { + segment_span_until_end: Span::from( + ident.span().start()..use_tree.span.end() - 1, + ), + }, + ); + } + UseTreeKind::List(use_trees) => { + if let Some(first_use_tree) = use_trees.first() { + self.insert_use_segment_position( + prefix, + UseSegmentPosition::BeforeList { + first_entry_span: first_use_tree.prefix.span(), + list_is_empty: false, + }, + ); + } else { + self.insert_use_segment_position( + prefix, + UseSegmentPosition::BeforeList { + first_entry_span: Span::from( + use_tree.span.end() - 1..use_tree.span.end() - 1, + ), + list_is_empty: true, + }, + ); + } + } + } + } + + fn insert_use_segment_position(&mut self, segment: String, position: UseSegmentPosition) { + if self.use_segment_positions.get(&segment).is_none() { + self.use_segment_positions.insert(segment, position); + } else { + self.use_segment_positions.insert(segment, UseSegmentPosition::NoneOrMultiple); + } + } +} + +pub(crate) struct UseCompletionItemAdditionTextEditsRequest<'a> { + /// The full path of the use statement to insert + pub(crate) full_path: &'a str, + pub(crate) files: &'a FileMap, + pub(crate) file: FileId, + /// All of the current source lines + pub(crate) lines: &'a Vec<&'a str>, + /// How many nested `mod` we are in deep + pub(crate) nesting: usize, + /// The line where an auto_import must be inserted + pub(crate) auto_import_line: usize, +} + +/// Returns the text edits needed to add an auto-import for a given full path. +pub(crate) fn use_completion_item_additional_text_edits( + request: UseCompletionItemAdditionTextEditsRequest, + positions: &UseSegmentPositions, +) -> Vec { + let (use_segment_position, name) = positions.get(request.full_path); + match use_segment_position { + UseSegmentPosition::NoneOrMultiple => { + // The parent path either isn't in any use statement, or it exists in multiple + // use statements. In either case we'll add a new use statement. + + new_use_completion_item_additional_text_edits(request) + } + UseSegmentPosition::Last { span } => { + // We have + // + // use foo::bar; + // ^^^ -> span + // + // and we want to transform it to: + // + // use foo::bar::{self, baz}; + // ^^^^^^^^^^^^^ + // + // So we need one text edit: + // 1. insert "::{self, baz}" right after the span + if let Some(lsp_location) = to_lsp_location(request.files, request.file, span) { + let range = lsp_location.range; + vec![TextEdit { + new_text: format!("::{{self, {}}}", name), + range: Range { start: range.end, end: range.end }, + }] + } else { + new_use_completion_item_additional_text_edits(request) + } + } + UseSegmentPosition::BeforeSegment { segment_span_until_end } => { + // Go past the end + let segment_span_until_end = + Span::from(segment_span_until_end.start()..segment_span_until_end.end() + 1); + + // We have + // + // use foo::bar::{one, two}; + // ^^^^^^^^^^^^^^^ -> segment_span_until_end + // + // and we want to transform it to: + // + // use foo::{bar::{one, two}, baz}; + // ^ ^^^^^^ + // + // So we need two text edits: + // 1. insert "{" right before the segment span + // 2. insert ", baz}" right after the segment span + if let Some(lsp_location) = + to_lsp_location(request.files, request.file, segment_span_until_end) + { + let range = lsp_location.range; + vec![ + TextEdit { + new_text: "{".to_string(), + range: Range { start: range.start, end: range.start }, + }, + TextEdit { + new_text: format!(", {}}}", name), + range: Range { start: range.end, end: range.end }, + }, + ] + } else { + new_use_completion_item_additional_text_edits(request) + } + } + UseSegmentPosition::BeforeList { first_entry_span, list_is_empty } => { + // We have + // + // use foo::bar::{one, two}; + // ^^^ -> first_entry_span + // + // and we want to transform it to: + // + // use foo::bar::{baz, one, two}; + // ^^^^ + // + // So we need one text edit: + // 1. insert "baz, " right before the first entry span + if let Some(lsp_location) = + to_lsp_location(request.files, request.file, first_entry_span) + { + let range = lsp_location.range; + vec![TextEdit { + new_text: if list_is_empty { name } else { format!("{}, ", name) }, + range: Range { start: range.start, end: range.start }, + }] + } else { + new_use_completion_item_additional_text_edits(request) + } + } + } +} + +fn new_use_completion_item_additional_text_edits( + request: UseCompletionItemAdditionTextEditsRequest, +) -> Vec { + let line = request.auto_import_line as u32; + let character = (request.nesting * 4) as u32; + let indent = " ".repeat(request.nesting * 4); + let mut newlines = "\n"; + + // If the line we are inserting into is not an empty line, insert an extra line to make some room + if let Some(line_text) = request.lines.get(line as usize) { + if !line_text.trim().is_empty() { + newlines = "\n\n"; + } + } + + vec![TextEdit { + range: Range { start: Position { line, character }, end: Position { line, character } }, + new_text: format!("use {};{}{}", request.full_path, newlines, indent), + }] +} diff --git a/noir/noir-repo/tooling/nargo/src/ops/execute.rs b/noir/noir-repo/tooling/nargo/src/ops/execute.rs index eb03bdf01c1..09ef554d2aa 100644 --- a/noir/noir-repo/tooling/nargo/src/ops/execute.rs +++ b/noir/noir-repo/tooling/nargo/src/ops/execute.rs @@ -3,7 +3,9 @@ use acvm::acir::circuit::{ OpcodeLocation, Program, ResolvedAssertionPayload, ResolvedOpcodeLocation, }; use acvm::acir::native_types::WitnessStack; -use acvm::pwg::{ACVMStatus, ErrorLocation, OpcodeNotSolvable, OpcodeResolutionError, ACVM}; +use acvm::pwg::{ + ACVMStatus, ErrorLocation, OpcodeNotSolvable, OpcodeResolutionError, ProfilingSamples, ACVM, +}; use acvm::{acir::circuit::Circuit, acir::native_types::WitnessMap}; use acvm::{AcirField, BlackBoxFunctionSolver}; @@ -32,6 +34,10 @@ struct ProgramExecutor<'a, F, B: BlackBoxFunctionSolver, E: ForeignCallExecut // This is used to fetch the function we want to execute // and to resolve call stack locations across many function calls. current_function_index: usize, + + // Flag that states whether we want to profile the VM. Profiling can add extra + // execution costs so we want to make sure we only trigger it explicitly. + profiling_active: bool, } impl<'a, F: AcirField, B: BlackBoxFunctionSolver, E: ForeignCallExecutor> @@ -42,6 +48,7 @@ impl<'a, F: AcirField, B: BlackBoxFunctionSolver, E: ForeignCallExecutor> unconstrained_functions: &'a [BrilligBytecode], blackbox_solver: &'a B, foreign_call_executor: &'a mut E, + profiling_active: bool, ) -> Self { ProgramExecutor { functions, @@ -51,6 +58,7 @@ impl<'a, F: AcirField, B: BlackBoxFunctionSolver, E: ForeignCallExecutor> foreign_call_executor, call_stack: Vec::default(), current_function_index: 0, + profiling_active, } } @@ -62,7 +70,7 @@ impl<'a, F: AcirField, B: BlackBoxFunctionSolver, E: ForeignCallExecutor> fn execute_circuit( &mut self, initial_witness: WitnessMap, - ) -> Result, NargoError> { + ) -> Result<(WitnessMap, ProfilingSamples), NargoError> { let circuit = &self.functions[self.current_function_index]; let mut acvm = ACVM::new( self.blackbox_solver, @@ -71,6 +79,7 @@ impl<'a, F: AcirField, B: BlackBoxFunctionSolver, E: ForeignCallExecutor> self.unconstrained_functions, &circuit.assert_messages, ); + acvm.with_profiler(self.profiling_active); loop { let solver_status = acvm.solve(); @@ -155,7 +164,8 @@ impl<'a, F: AcirField, B: BlackBoxFunctionSolver, E: ForeignCallExecutor> // Execute the ACIR call let acir_to_call = &self.functions[call_info.id.as_usize()]; let initial_witness = call_info.initial_witness; - let call_solved_witness = self.execute_circuit(initial_witness)?; + // TODO: Profiling among multiple circuits is not supported + let (call_solved_witness, _) = self.execute_circuit(initial_witness)?; // Set tracking index back to the parent function after ACIR call execution self.current_function_index = acir_function_caller; @@ -184,25 +194,67 @@ impl<'a, F: AcirField, B: BlackBoxFunctionSolver, E: ForeignCallExecutor> // included in a failure case. self.call_stack.clear(); - Ok(acvm.finalize()) + let profiling_samples = acvm.take_profiling_samples(); + Ok((acvm.finalize(), profiling_samples)) } } -#[tracing::instrument(level = "trace", skip_all)] pub fn execute_program, E: ForeignCallExecutor>( program: &Program, initial_witness: WitnessMap, blackbox_solver: &B, foreign_call_executor: &mut E, ) -> Result, NargoError> { + let profiling_active = false; + let (witness_stack, profiling_samples) = execute_program_inner( + program, + initial_witness, + blackbox_solver, + foreign_call_executor, + profiling_active, + )?; + assert!(profiling_samples.is_empty(), "Expected no profiling samples"); + + Ok(witness_stack) +} + +pub fn execute_program_with_profiling< + F: AcirField, + B: BlackBoxFunctionSolver, + E: ForeignCallExecutor, +>( + program: &Program, + initial_witness: WitnessMap, + blackbox_solver: &B, + foreign_call_executor: &mut E, +) -> Result<(WitnessStack, ProfilingSamples), NargoError> { + let profiling_active = true; + execute_program_inner( + program, + initial_witness, + blackbox_solver, + foreign_call_executor, + profiling_active, + ) +} + +#[tracing::instrument(level = "trace", skip_all)] +fn execute_program_inner, E: ForeignCallExecutor>( + program: &Program, + initial_witness: WitnessMap, + blackbox_solver: &B, + foreign_call_executor: &mut E, + profiling_active: bool, +) -> Result<(WitnessStack, ProfilingSamples), NargoError> { let mut executor = ProgramExecutor::new( &program.functions, &program.unconstrained_functions, blackbox_solver, foreign_call_executor, + profiling_active, ); - let main_witness = executor.execute_circuit(initial_witness)?; + let (main_witness, profiling_samples) = executor.execute_circuit(initial_witness)?; executor.witness_stack.push(0, main_witness); - Ok(executor.finalize()) + Ok((executor.finalize(), profiling_samples)) } diff --git a/noir/noir-repo/tooling/nargo/src/ops/mod.rs b/noir/noir-repo/tooling/nargo/src/ops/mod.rs index cada2f0e915..16680dab980 100644 --- a/noir/noir-repo/tooling/nargo/src/ops/mod.rs +++ b/noir/noir-repo/tooling/nargo/src/ops/mod.rs @@ -2,7 +2,7 @@ pub use self::compile::{ collect_errors, compile_contract, compile_program, compile_program_with_debug_instrumenter, compile_workspace, report_errors, }; -pub use self::execute::execute_program; +pub use self::execute::{execute_program, execute_program_with_profiling}; pub use self::foreign_calls::{DefaultForeignCallExecutor, ForeignCall, ForeignCallExecutor}; pub use self::optimize::{optimize_contract, optimize_program}; pub use self::transform::{transform_contract, transform_program}; diff --git a/noir/noir-repo/tooling/nargo_cli/Cargo.toml b/noir/noir-repo/tooling/nargo_cli/Cargo.toml index d72556ab936..d48e44415b0 100644 --- a/noir/noir-repo/tooling/nargo_cli/Cargo.toml +++ b/noir/noir-repo/tooling/nargo_cli/Cargo.toml @@ -86,6 +86,7 @@ sha2.workspace = true sha3.workspace = true iai = "0.1.1" test-binary = "3.0.2" +test-case.workspace = true light-poseidon = "0.2.0" diff --git a/noir/noir-repo/tooling/nargo_cli/tests/stdlib-tests.rs b/noir/noir-repo/tooling/nargo_cli/tests/stdlib-tests.rs index d27a2961a62..bdc92e625ab 100644 --- a/noir/noir-repo/tooling/nargo_cli/tests/stdlib-tests.rs +++ b/noir/noir-repo/tooling/nargo_cli/tests/stdlib-tests.rs @@ -1,4 +1,5 @@ //! Execute unit tests in the Noir standard library. +#![allow(clippy::items_after_test_module)] use clap::Parser; use fm::FileManager; use noirc_driver::{check_crate, file_manager_with_stdlib, CompileOptions}; @@ -12,6 +13,7 @@ use nargo::{ parse_all, prepare_package, }; use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor}; +use test_case::test_matrix; #[derive(Parser, Debug)] #[command(ignore_errors = true)] @@ -29,14 +31,22 @@ pub struct Options { impl Options { pub fn function_name_match(&self) -> FunctionNameMatch { match self.args.as_slice() { - [_, lib] => FunctionNameMatch::Contains(lib.as_str()), + [_test_name, lib] => FunctionNameMatch::Contains(lib.as_str()), _ => FunctionNameMatch::Anything, } } } -#[test] -fn run_stdlib_tests() { +/// Inliner aggressiveness results in different SSA. +/// Inlining happens if `inline_cost - retain_cost < aggressiveness` (see `inlining.rs`). +/// NB the CLI uses maximum aggressiveness. +/// +/// Even with the same inlining aggressiveness, forcing Brillig can trigger different behaviour. +#[test_matrix( + [false, true], + [i64::MIN, 0, i64::MAX] +)] +fn run_stdlib_tests(force_brillig: bool, inliner_aggressiveness: i64) { let opts = Options::parse(); let mut file_manager = file_manager_with_stdlib(&PathBuf::from(".")); @@ -76,11 +86,11 @@ fn run_stdlib_tests() { &bn254_blackbox_solver::Bn254BlackBoxSolver, &mut context, &test_function, - false, + true, None, Some(dummy_package.root_dir.clone()), Some(dummy_package.name.to_string()), - &CompileOptions::default(), + &CompileOptions { force_brillig, inliner_aggressiveness, ..Default::default() }, ); (test_name, status) }) diff --git a/noir/noir-repo/tooling/nargo_fmt/src/chunks.rs b/noir/noir-repo/tooling/nargo_fmt/src/chunks.rs index 073e03ea74a..673cf020aed 100644 --- a/noir/noir-repo/tooling/nargo_fmt/src/chunks.rs +++ b/noir/noir-repo/tooling/nargo_fmt/src/chunks.rs @@ -466,7 +466,11 @@ pub(crate) enum GroupKind { /// fit in the current line and it's not a block, instead of splitting that expression /// somewhere that's probably undesired, we'll "turn it" into a block /// (write the "{" and "}" delimiters) and write the lambda body in the next line. - LambdaBody { is_block: bool }, + LambdaBody { + block_statement_count: Option, + has_comments: bool, + lambda_has_return_type: bool, + }, /// A method call. /// We track all this information to see, if we end up needing to format this call /// in multiple lines, if we can write everything up to the left parentheses (inclusive) @@ -762,14 +766,14 @@ impl<'a> Formatter<'a> { // If a lambda body doesn't fit in the current line and it's not a block, // we can turn it into a block and write it in the next line, so its contents fit. - if let GroupKind::LambdaBody { is_block: false } = group.kind { + if let GroupKind::LambdaBody { block_statement_count: None, .. } = group.kind { // Try to format it again in the next line, but we don't want to recurse // infinitely so we change the group kind. group.kind = GroupKind::Regular; self.write("{"); self.trim_spaces(); self.increase_indentation(); - self.write_line(); + self.write_line_without_skipping_whitespace_and_comments(); self.write_indentation(); self.format_chunk_group_impl(group); @@ -803,7 +807,7 @@ impl<'a> Formatter<'a> { // ) let comma_trimmed = self.trim_comma(); self.decrease_indentation(); - self.write_line(); + self.write_line_without_skipping_whitespace_and_comments(); self.write_indentation(); self.write("}"); if comma_trimmed { @@ -816,6 +820,24 @@ impl<'a> Formatter<'a> { return; } + // At this point we determined we are going to write this group in a single line. + // If the current group is a lambda body that is a block with a single statement, like this: + // + // |x| { 1 + 2 } + // + // given that we determined the block fits the current line, if we remove the surrounding + // `{ .. }` it will still fit the current line, and reduce some noise from the code + // (this is what rustfmt seems to do too). + if let GroupKind::LambdaBody { + block_statement_count: Some(1), + has_comments: false, + lambda_has_return_type: false, + } = group.kind + { + self.format_lambda_body_removing_braces(group); + return; + } + self.format_chunk_group_in_one_line(group); } @@ -827,10 +849,10 @@ impl<'a> Formatter<'a> { } Chunk::TrailingComment(text_chunk) | Chunk::LeadingComment(text_chunk) => { self.write(&text_chunk.string); - self.write(" "); + self.write_space_without_skipping_whitespace_and_comments(); } Chunk::Group(chunks) => self.format_chunk_group_impl(chunks), - Chunk::SpaceOrLine => self.write(" "), + Chunk::SpaceOrLine => self.write_space_without_skipping_whitespace_and_comments(), Chunk::IncreaseIndentation => self.increase_indentation(), Chunk::DecreaseIndentation => self.decrease_indentation(), Chunk::PushIndentation => self.push_indentation(), @@ -893,9 +915,16 @@ impl<'a> Formatter<'a> { self.write_indentation(); } Chunk::LeadingComment(text_chunk) => { + let ends_with_newline = text_chunk.string.ends_with('\n'); self.write_chunk_lines(text_chunk.string.trim()); - self.write_line_without_skipping_whitespace_and_comments(); - self.write_indentation(); + + // Respect whether the leading comment had a newline before what comes next or not + if ends_with_newline { + self.write_line_without_skipping_whitespace_and_comments(); + self.write_indentation(); + } else { + self.write_space_without_skipping_whitespace_and_comments(); + } } Chunk::Group(mut group) => { if chunks.force_multiline_on_children_with_same_tag_if_multiline @@ -939,6 +968,31 @@ impl<'a> Formatter<'a> { } } + fn format_lambda_body_removing_braces(&mut self, group: ChunkGroup) { + // Write to an intermediate string so we can remove the braces if needed. + let text_chunk = self.chunk_formatter().chunk(|formatter| { + formatter.format_chunk_group_in_one_line(group); + }); + let string = text_chunk.string; + + // Don't remove the braces if the lambda's body is a Semi expression. + if string.ends_with("; }") || string.ends_with("; },") { + self.write(&string); + return; + } + + let string = string.strip_prefix("{ ").unwrap(); + + // The lambda might have a trailing comma if it's inside an arguments list + if let Some(string) = string.strip_suffix(" },") { + self.write(string); + self.write(","); + } else { + let string = string.strip_suffix(" }").unwrap(); + self.write(string); + } + } + /// Appends the string to the current buffer line by line, with some pre-checks. fn write_chunk_lines(&mut self, string: &str) { for (index, line) in string.lines().enumerate() { diff --git a/noir/noir-repo/tooling/nargo_fmt/src/formatter/comments_and_whitespace.rs b/noir/noir-repo/tooling/nargo_fmt/src/formatter/comments_and_whitespace.rs index e5f15bc397e..4aba0481e24 100644 --- a/noir/noir-repo/tooling/nargo_fmt/src/formatter/comments_and_whitespace.rs +++ b/noir/noir-repo/tooling/nargo_fmt/src/formatter/comments_and_whitespace.rs @@ -301,8 +301,8 @@ mod tests { let src = "global x = [ /* hello */ 1 , 2 ] ;"; let expected = "global x = [ - /* hello */ - 1, 2, + /* hello */ 1, + 2, ]; "; assert_format_with_max_width(src, expected, 20); diff --git a/noir/noir-repo/tooling/nargo_fmt/src/formatter/expression.rs b/noir/noir-repo/tooling/nargo_fmt/src/formatter/expression.rs index 6f7ebf56348..ebfa3ae78fb 100644 --- a/noir/noir-repo/tooling/nargo_fmt/src/formatter/expression.rs +++ b/noir/noir-repo/tooling/nargo_fmt/src/formatter/expression.rs @@ -198,6 +198,8 @@ impl<'a, 'b> ChunkFormatter<'a, 'b> { fn format_lambda(&mut self, lambda: Lambda) -> FormattedLambda { let mut group = ChunkGroup::new(); + let lambda_has_return_type = lambda.return_type.typ != UnresolvedTypeData::Unspecified; + let params_and_return_type_chunk = self.chunk(|formatter| { formatter.write_token(Token::Pipe); for (index, (pattern, typ)) in lambda.parameters.into_iter().enumerate() { @@ -218,7 +220,7 @@ impl<'a, 'b> ChunkFormatter<'a, 'b> { } formatter.write_token(Token::Pipe); formatter.write_space(); - if lambda.return_type.typ != UnresolvedTypeData::Unspecified { + if lambda_has_return_type { formatter.write_token(Token::Arrow); formatter.write_space(); formatter.format_type(lambda.return_type); @@ -230,16 +232,27 @@ impl<'a, 'b> ChunkFormatter<'a, 'b> { group.text(params_and_return_type_chunk); - let body_is_block = matches!(lambda.body.kind, ExpressionKind::Block(..)); + let block_statement_count = if let ExpressionKind::Block(block) = &lambda.body.kind { + Some(block.statements.len()) + } else { + None + }; let mut body_group = ChunkGroup::new(); - body_group.kind = GroupKind::LambdaBody { is_block: body_is_block }; + let comments_count_before_body = self.written_comments_count; self.format_expression(lambda.body, &mut body_group); + + body_group.kind = GroupKind::LambdaBody { + block_statement_count, + has_comments: self.written_comments_count > comments_count_before_body, + lambda_has_return_type, + }; + group.group(body_group); let first_line_width = params_and_return_type_chunk_width - + (if body_is_block { + + (if block_statement_count.is_some() { // 1 because we already have `|param1, param2, ..., paramN| ` (including the space) // so all that's left is a `{`. 1 @@ -433,23 +446,22 @@ impl<'a, 'b> ChunkFormatter<'a, 'b> { { let mut comments_chunk = self.skip_comments_and_whitespace_chunk(); - // If the comment is not empty but doesn't have newlines, it's surely `/* comment */`. - // We format that with spaces surrounding it so it looks, for example, like `Foo { /* comment */ field ..`. - if !comments_chunk.string.trim().is_empty() && !comments_chunk.has_newlines { - // Note: there's no space after `{}` because space will be produced by format_items_separated_by_comma - comments_chunk.string = if surround_with_spaces { - format!(" {}", comments_chunk.string.trim()) - } else { - format!(" {} ", comments_chunk.string.trim()) - }; - group.text(comments_chunk); - + // Handle leading block vs. line comments a bit differently. + if comments_chunk.string.trim().starts_with("/*") { group.increase_indentation(); if surround_with_spaces { group.space_or_line(); } else { group.line(); } + + // Note: there's no space before `{}` because it was just produced + comments_chunk.string = if surround_with_spaces { + comments_chunk.string.trim().to_string() + } else { + format!("{} ", comments_chunk.string.trim()) + }; + group.leading_comment(comments_chunk); } else { group.increase_indentation(); if surround_with_spaces { @@ -466,7 +478,24 @@ impl<'a, 'b> ChunkFormatter<'a, 'b> { group.text_attached_to_last_group(self.chunk(|formatter| { formatter.write_comma(); })); - group.trailing_comment(self.skip_comments_and_whitespace_chunk()); + let newlines_count_before_comment = self.following_newlines_count(); + group.text(self.chunk(|formatter| { + formatter.skip_whitespace(); + })); + if let Token::BlockComment(..) = &self.token { + // We let block comments be part of the item that's going to be formatted + } else { + // Line comments can be trailing or leading, depending on whether there are newlines before them + let comments_and_whitespace_chunk = self.skip_comments_and_whitespace_chunk(); + if !comments_and_whitespace_chunk.string.trim().is_empty() { + if newlines_count_before_comment > 0 { + group.line(); + group.leading_comment(comments_and_whitespace_chunk); + } else { + group.trailing_comment(comments_and_whitespace_chunk); + } + } + } group.space_or_line(); } format_item(self, expr, group); @@ -1313,6 +1342,56 @@ global y = 1; assert_format_with_config(src, expected, config); } + #[test] + fn format_short_array_with_block_comment_before_elements() { + let src = "global x = [ /* one */ 1, /* two */ 2 ] ;"; + let expected = "global x = [/* one */ 1, /* two */ 2];\n"; + + assert_format(src, expected); + } + + #[test] + fn format_long_array_with_block_comment_before_elements() { + let src = "global x = [ /* one */ 1, /* two */ 123456789012345, 3, 4 ] ;"; + let expected = "global x = [ + /* one */ 1, + /* two */ 123456789012345, + 3, + 4, +]; +"; + + let config = + Config { short_array_element_width_threshold: 5, max_width: 30, ..Config::default() }; + assert_format_with_config(src, expected, config); + } + + #[test] + fn format_long_array_with_line_comment_before_elements() { + let src = "global x = [ + // one + 1, + // two + 123456789012345, + 3, + 4, +]; +"; + let expected = "global x = [ + // one + 1, + // two + 123456789012345, + 3, + 4, +]; +"; + + let config = + Config { short_array_element_width_threshold: 5, max_width: 30, ..Config::default() }; + assert_format_with_config(src, expected, config); + } + #[test] fn format_cast() { let src = "global x = 1 as u8 ;"; @@ -1980,12 +2059,44 @@ global y = 1; } #[test] - fn format_lambda_with_block() { + fn format_lambda_with_block_simplifies() { let src = "global x = | | { 1 } ;"; - let expected = "global x = || { 1 };\n"; + let expected = "global x = || 1;\n"; assert_format(src, expected); } + #[test] + fn format_lambda_with_block_does_not_simplify_if_it_ends_with_semicolon() { + let src = "global x = | | { 1; } ;"; + let expected = "global x = || { 1; };\n"; + assert_format(src, expected); + } + + #[test] + fn format_lambda_with_block_does_not_simplify_if_it_has_return_type() { + let src = "global x = | | -> i32 { 1 } ;"; + let expected = "global x = || -> i32 { 1 };\n"; + assert_format(src, expected); + } + + #[test] + fn format_lambda_with_simplifies_block_with_quote() { + let src = "global x = | | { quote { 1 } } ;"; + let expected = "global x = || quote { 1 };\n"; + assert_format(src, expected); + } + + #[test] + fn format_lambda_with_block_simplifies_inside_arguments_list() { + let src = "global x = some_call(this_is_a_long_argument, | | { 1 });"; + let expected = "global x = some_call( + this_is_a_long_argument, + || 1, +); +"; + assert_format_with_max_width(src, expected, 20); + } + #[test] fn format_lambda_with_block_multiple_statements() { let src = "global x = | a, b | { 1; 2 } ;"; diff --git a/noir/noir-repo/tooling/nargo_fmt/src/formatter/statement.rs b/noir/noir-repo/tooling/nargo_fmt/src/formatter/statement.rs index b0692d2d631..28107294909 100644 --- a/noir/noir-repo/tooling/nargo_fmt/src/formatter/statement.rs +++ b/noir/noir-repo/tooling/nargo_fmt/src/formatter/statement.rs @@ -568,10 +568,10 @@ mod tests { #[test] fn format_two_for_separated_by_multiple_lines() { - let src = " fn foo() { for x in array { 1 } - + let src = " fn foo() { for x in array { 1 } + for x in array { 1 } - + } "; let expected = "fn foo() { for x in array { diff --git a/noir/noir-repo/tooling/nargo_fmt/src/formatter/use_tree.rs b/noir/noir-repo/tooling/nargo_fmt/src/formatter/use_tree.rs index bc8dc3fcabb..98d63ef6611 100644 --- a/noir/noir-repo/tooling/nargo_fmt/src/formatter/use_tree.rs +++ b/noir/noir-repo/tooling/nargo_fmt/src/formatter/use_tree.rs @@ -211,7 +211,7 @@ mod tests { #[test] fn format_use_list_one_item_with_comments() { let src = " use foo::{ /* do not remove me */ bar, };"; - let expected = "use foo::{ /* do not remove me */ bar};\n"; + let expected = "use foo::{/* do not remove me */ bar};\n"; assert_format(src, expected); } diff --git a/noir/noir-repo/tooling/nargo_fmt/src/formatter/use_tree_merge.rs b/noir/noir-repo/tooling/nargo_fmt/src/formatter/use_tree_merge.rs index e24b7b8cbf6..834280ddba3 100644 --- a/noir/noir-repo/tooling/nargo_fmt/src/formatter/use_tree_merge.rs +++ b/noir/noir-repo/tooling/nargo_fmt/src/formatter/use_tree_merge.rs @@ -397,7 +397,7 @@ mod tests { #[test] fn format_use_list_one_item_with_comments() { let src = " use foo::{ /* do not remove me */ bar, };"; - let expected = "use foo::{ /* do not remove me */ bar};\n"; + let expected = "use foo::{/* do not remove me */ bar};\n"; assert_format(src, expected); } diff --git a/noir/noir-repo/tooling/nargo_fmt/tests/expected/contract.nr b/noir/noir-repo/tooling/nargo_fmt/tests/expected/contract.nr index ad53e61c911..86f8d56b62d 100644 --- a/noir/noir-repo/tooling/nargo_fmt/tests/expected/contract.nr +++ b/noir/noir-repo/tooling/nargo_fmt/tests/expected/contract.nr @@ -34,7 +34,7 @@ contract Benchmarking { notes: Map::new( context, 1, - |context, slot| { PrivateSet::new(context, slot, ValueNoteMethods) }, + |context, slot| PrivateSet::new(context, slot, ValueNoteMethods), ), balances: Map::new( context, diff --git a/noir/noir-repo/tooling/nargo_fmt/tests/expected/tuple.nr b/noir/noir-repo/tooling/nargo_fmt/tests/expected/tuple.nr index d4b8b239815..29f32f83e55 100644 --- a/noir/noir-repo/tooling/nargo_fmt/tests/expected/tuple.nr +++ b/noir/noir-repo/tooling/nargo_fmt/tests/expected/tuple.nr @@ -4,13 +4,13 @@ fn main() { // hello 1, ); - ( /*hello*/ 1,); + (/*hello*/ 1,); (1/*hello*/,); (1,); - ( /*test*/ 1,); - ( /*a*/ 1/*b*/,); - ( /*a*/ 1/*b*/, /*c*/ 2/*d*/, /*c*/ 2/*d*/); - ( /*a*/ 1/*b*/, /*c*/ 2/*d*/, /*c*/ 2/*d*/, /*e*/ 3/*f*/); + (/*test*/ 1,); + (/*a*/ 1/*b*/,); + (/*a*/ 1/*b*/, /*c*/ 2/*d*/, /*c*/ 2/*d*/); + (/*a*/ 1/*b*/, /*c*/ 2/*d*/, /*c*/ 2/*d*/, /*e*/ 3/*f*/); (1 /*1*/, 2 /* 2*/); @@ -28,7 +28,7 @@ fn main() { 2, ); - ( /*1*/ 1, /*2*/ 2); + (/*1*/ 1, /*2*/ 2); ( ( @@ -39,14 +39,8 @@ fn main() { ), ); ( - /*a*/ - 1 - /*b*/, - /*c*/ - 2/*d*/, - /*c*/ - 2/*d*/, - /*e*/ - 3,/*f*/ + /*a*/ 1 + /*b*/, /*c*/ + 2/*d*/, /*c*/ 2/*d*/, /*e*/ 3,/*f*/ ); } diff --git a/noir/noir-repo/tooling/noirc_abi_wasm/build.sh b/noir/noir-repo/tooling/noirc_abi_wasm/build.sh index c07d2d8a4c1..16fb26e55db 100755 --- a/noir/noir-repo/tooling/noirc_abi_wasm/build.sh +++ b/noir/noir-repo/tooling/noirc_abi_wasm/build.sh @@ -25,7 +25,7 @@ function run_if_available { require_command jq require_command cargo require_command wasm-bindgen -#require_command wasm-opt +require_command wasm-opt self_path=$(dirname "$(readlink -f "$0")") pname=$(cargo read-manifest | jq -r '.name') diff --git a/noir/noir-repo/tooling/profiler/Cargo.toml b/noir/noir-repo/tooling/profiler/Cargo.toml index 136775d5831..c76b4c73e65 100644 --- a/noir/noir-repo/tooling/profiler/Cargo.toml +++ b/noir/noir-repo/tooling/profiler/Cargo.toml @@ -18,8 +18,10 @@ name = "noir-profiler" path = "src/main.rs" [dependencies] +bn254_blackbox_solver.workspace = true color-eyre.workspace = true clap.workspace = true +fxhash.workspace = true noirc_artifacts.workspace = true const_format.workspace = true serde.workspace = true @@ -28,7 +30,9 @@ fm.workspace = true inferno = "0.11.19" im.workspace = true acir.workspace = true +nargo.workspace = true noirc_errors.workspace = true +noirc_abi.workspace = true # Logs tracing-subscriber.workspace = true diff --git a/noir/noir-repo/tooling/profiler/src/cli/execution_flamegraph_cmd.rs b/noir/noir-repo/tooling/profiler/src/cli/execution_flamegraph_cmd.rs new file mode 100644 index 00000000000..a0b3d6a3128 --- /dev/null +++ b/noir/noir-repo/tooling/profiler/src/cli/execution_flamegraph_cmd.rs @@ -0,0 +1,96 @@ +use std::path::{Path, PathBuf}; + +use acir::circuit::OpcodeLocation; +use acir::FieldElement; +use clap::Args; +use color_eyre::eyre::{self, Context}; + +use crate::flamegraph::{FlamegraphGenerator, InfernoFlamegraphGenerator, Sample}; +use crate::fs::{read_inputs_from_file, read_program_from_file}; +use crate::opcode_formatter::AcirOrBrilligOpcode; +use bn254_blackbox_solver::Bn254BlackBoxSolver; +use nargo::ops::DefaultForeignCallExecutor; +use noirc_abi::input_parser::Format; +use noirc_artifacts::debug::DebugArtifact; + +#[derive(Debug, Clone, Args)] +pub(crate) struct ExecutionFlamegraphCommand { + /// The path to the artifact JSON file + #[clap(long, short)] + artifact_path: PathBuf, + + /// The path to the Prover.toml file + #[clap(long, short)] + prover_toml_path: PathBuf, + + /// The output folder for the flamegraph svg files + #[clap(long, short)] + output: PathBuf, +} + +pub(crate) fn run(args: ExecutionFlamegraphCommand) -> eyre::Result<()> { + run_with_generator( + &args.artifact_path, + &args.prover_toml_path, + &InfernoFlamegraphGenerator { count_name: "samples".to_string() }, + &args.output, + ) +} + +fn run_with_generator( + artifact_path: &Path, + prover_toml_path: &Path, + flamegraph_generator: &impl FlamegraphGenerator, + output_path: &Path, +) -> eyre::Result<()> { + let program = + read_program_from_file(artifact_path).context("Error reading program from file")?; + + let (inputs_map, _) = read_inputs_from_file(prover_toml_path, Format::Toml, &program.abi)?; + + let initial_witness = program.abi.encode(&inputs_map, None)?; + + println!("Executing"); + let (_, profiling_samples) = nargo::ops::execute_program_with_profiling( + &program.bytecode, + initial_witness, + &Bn254BlackBoxSolver, + &mut DefaultForeignCallExecutor::new(true, None, None, None), + )?; + println!("Executed"); + + let profiling_samples: Vec> = profiling_samples + .into_iter() + .map(|sample| { + let call_stack = sample.call_stack; + let brillig_function_id = sample.brillig_function_id; + let last_entry = call_stack.last(); + let opcode = brillig_function_id + .and_then(|id| program.bytecode.unconstrained_functions.get(id.0 as usize)) + .and_then(|func| { + if let Some(OpcodeLocation::Brillig { brillig_index, .. }) = last_entry { + func.bytecode.get(*brillig_index) + } else { + None + } + }) + .map(|opcode| AcirOrBrilligOpcode::Brillig(opcode.clone())); + Sample { opcode, call_stack, count: 1, brillig_function_id } + }) + .collect(); + + let debug_artifact: DebugArtifact = program.into(); + + println!("Generating flamegraph with {} samples", profiling_samples.len()); + + flamegraph_generator.generate_flamegraph( + profiling_samples, + &debug_artifact.debug_symbols[0], + &debug_artifact, + artifact_path.to_str().unwrap(), + "main", + &Path::new(&output_path).join(Path::new(&format!("{}.svg", "main"))), + )?; + + Ok(()) +} diff --git a/noir/noir-repo/tooling/profiler/src/cli/gates_flamegraph_cmd.rs b/noir/noir-repo/tooling/profiler/src/cli/gates_flamegraph_cmd.rs index d5fefc4ecda..20cc1b747c3 100644 --- a/noir/noir-repo/tooling/profiler/src/cli/gates_flamegraph_cmd.rs +++ b/noir/noir-repo/tooling/profiler/src/cli/gates_flamegraph_cmd.rs @@ -84,7 +84,7 @@ fn run_with_provider( .zip(bytecode.opcodes) .enumerate() .map(|(index, (gates, opcode))| Sample { - opcode: AcirOrBrilligOpcode::Acir(opcode), + opcode: Some(AcirOrBrilligOpcode::Acir(opcode)), call_stack: vec![OpcodeLocation::Acir(index)], count: gates, brillig_function_id: None, diff --git a/noir/noir-repo/tooling/profiler/src/cli/mod.rs b/noir/noir-repo/tooling/profiler/src/cli/mod.rs index 7cfc6ed7c9e..80c6bceb3ce 100644 --- a/noir/noir-repo/tooling/profiler/src/cli/mod.rs +++ b/noir/noir-repo/tooling/profiler/src/cli/mod.rs @@ -2,6 +2,7 @@ use clap::{Parser, Subcommand}; use color_eyre::eyre; use const_format::formatcp; +mod execution_flamegraph_cmd; mod gates_flamegraph_cmd; mod opcodes_flamegraph_cmd; @@ -19,15 +20,17 @@ struct ProfilerCli { #[non_exhaustive] #[derive(Subcommand, Clone, Debug)] enum ProfilerCommand { - GatesFlamegraph(gates_flamegraph_cmd::GatesFlamegraphCommand), - OpcodesFlamegraph(opcodes_flamegraph_cmd::OpcodesFlamegraphCommand), + Gates(gates_flamegraph_cmd::GatesFlamegraphCommand), + Opcodes(opcodes_flamegraph_cmd::OpcodesFlamegraphCommand), + ExecutionOpcodes(execution_flamegraph_cmd::ExecutionFlamegraphCommand), } pub(crate) fn start_cli() -> eyre::Result<()> { let ProfilerCli { command } = ProfilerCli::parse(); match command { - ProfilerCommand::GatesFlamegraph(args) => gates_flamegraph_cmd::run(args), - ProfilerCommand::OpcodesFlamegraph(args) => opcodes_flamegraph_cmd::run(args), + ProfilerCommand::Gates(args) => gates_flamegraph_cmd::run(args), + ProfilerCommand::Opcodes(args) => opcodes_flamegraph_cmd::run(args), + ProfilerCommand::ExecutionOpcodes(args) => execution_flamegraph_cmd::run(args), } } diff --git a/noir/noir-repo/tooling/profiler/src/cli/opcodes_flamegraph_cmd.rs b/noir/noir-repo/tooling/profiler/src/cli/opcodes_flamegraph_cmd.rs index 863d45b96d1..bb3df86c339 100644 --- a/noir/noir-repo/tooling/profiler/src/cli/opcodes_flamegraph_cmd.rs +++ b/noir/noir-repo/tooling/profiler/src/cli/opcodes_flamegraph_cmd.rs @@ -60,7 +60,7 @@ fn run_with_generator( .iter() .enumerate() .map(|(index, opcode)| Sample { - opcode: AcirOrBrilligOpcode::Acir(opcode.clone()), + opcode: Some(AcirOrBrilligOpcode::Acir(opcode.clone())), call_stack: vec![OpcodeLocation::Acir(index)], count: 1, brillig_function_id: None, @@ -97,7 +97,7 @@ fn run_with_generator( .into_iter() .enumerate() .map(|(brillig_index, opcode)| Sample { - opcode: AcirOrBrilligOpcode::Brillig(opcode), + opcode: Some(AcirOrBrilligOpcode::Brillig(opcode)), call_stack: vec![OpcodeLocation::Brillig { acir_index: acir_opcode_index, brillig_index, diff --git a/noir/noir-repo/tooling/profiler/src/flamegraph.rs b/noir/noir-repo/tooling/profiler/src/flamegraph.rs index 488079de50a..a72168a20af 100644 --- a/noir/noir-repo/tooling/profiler/src/flamegraph.rs +++ b/noir/noir-repo/tooling/profiler/src/flamegraph.rs @@ -6,6 +6,7 @@ use acir::circuit::OpcodeLocation; use acir::AcirField; use color_eyre::eyre::{self}; use fm::codespan_files::Files; +use fxhash::FxHashMap as HashMap; use inferno::flamegraph::{from_lines, Options, TextTruncateDirection}; use noirc_errors::debug_info::DebugInfo; use noirc_errors::reporter::line_and_column_from_span; @@ -17,7 +18,7 @@ use super::opcode_formatter::format_opcode; #[derive(Debug)] pub(crate) struct Sample { - pub(crate) opcode: AcirOrBrilligOpcode, + pub(crate) opcode: Option>, pub(crate) call_stack: Vec, pub(crate) count: usize, pub(crate) brillig_function_id: Option, @@ -88,41 +89,61 @@ fn generate_folded_sorted_lines<'files, F: AcirField>( // Create a nested hashmap with the stack items, folding the gates for all the callsites that are equal let mut folded_stack_items = BTreeMap::new(); - samples.into_iter().for_each(|sample| { - let mut location_names: Vec = sample - .call_stack - .into_iter() - .flat_map(|opcode_location| { - debug_symbols.opcode_location(&opcode_location).unwrap_or_else(|| { - if let (Some(brillig_function_id), Some(brillig_location)) = - (sample.brillig_function_id, opcode_location.to_brillig_location()) - { - let brillig_locations = - debug_symbols.brillig_locations.get(&brillig_function_id); - if let Some(brillig_locations) = brillig_locations { - brillig_locations.get(&brillig_location).cloned().unwrap_or_default() - } else { - vec![] - } - } else { - vec![] - } + let mut resolution_cache: HashMap> = HashMap::default(); + for sample in samples { + let mut location_names = Vec::with_capacity(sample.call_stack.len()); + for opcode_location in sample.call_stack { + let callsite_labels = resolution_cache + .entry(opcode_location) + .or_insert_with(|| { + find_callsite_labels( + debug_symbols, + &opcode_location, + sample.brillig_function_id, + files, + ) }) - }) - .map(|location| location_to_callsite_label(location, files)) - .collect(); + .clone(); - if location_names.is_empty() { - location_names.push("unknown".to_string()); + location_names.extend(callsite_labels); } - location_names.push(format_opcode(&sample.opcode)); + if let Some(opcode) = &sample.opcode { + location_names.push(format_opcode(opcode)); + } add_locations_to_folded_stack_items(&mut folded_stack_items, location_names, sample.count); - }); + } to_folded_sorted_lines(&folded_stack_items, Default::default()) } +fn find_callsite_labels<'files>( + debug_symbols: &DebugInfo, + opcode_location: &OpcodeLocation, + brillig_function_id: Option, + files: &'files impl Files<'files, FileId = fm::FileId>, +) -> Vec { + let source_locations = debug_symbols.opcode_location(opcode_location).unwrap_or_else(|| { + if let (Some(brillig_function_id), Some(brillig_location)) = + (brillig_function_id, opcode_location.to_brillig_location()) + { + let brillig_locations = debug_symbols.brillig_locations.get(&brillig_function_id); + if let Some(brillig_locations) = brillig_locations { + brillig_locations.get(&brillig_location).cloned().unwrap_or_default() + } else { + vec![] + } + } else { + vec![] + } + }); + let callsite_labels: Vec<_> = source_locations + .into_iter() + .map(|location| location_to_callsite_label(location, files)) + .collect(); + callsite_labels +} + fn location_to_callsite_label<'files>( location: Location, files: &'files impl Files<'files, FileId = fm::FileId>, @@ -300,23 +321,27 @@ mod tests { let samples: Vec> = vec![ Sample { - opcode: AcirOrBrilligOpcode::Acir(AcirOpcode::AssertZero(Expression::default())), + opcode: Some(AcirOrBrilligOpcode::Acir(AcirOpcode::AssertZero( + Expression::default(), + ))), call_stack: vec![OpcodeLocation::Acir(0)], count: 10, brillig_function_id: None, }, Sample { - opcode: AcirOrBrilligOpcode::Acir(AcirOpcode::AssertZero(Expression::default())), + opcode: Some(AcirOrBrilligOpcode::Acir(AcirOpcode::AssertZero( + Expression::default(), + ))), call_stack: vec![OpcodeLocation::Acir(1)], count: 20, brillig_function_id: None, }, Sample { - opcode: AcirOrBrilligOpcode::Acir(AcirOpcode::MemoryInit { + opcode: Some(AcirOrBrilligOpcode::Acir(AcirOpcode::MemoryInit { block_id: BlockId(0), init: vec![], block_type: acir::circuit::opcodes::BlockType::Memory, - }), + })), call_stack: vec![OpcodeLocation::Acir(2)], count: 30, brillig_function_id: None, diff --git a/noir/noir-repo/tooling/profiler/src/fs.rs b/noir/noir-repo/tooling/profiler/src/fs.rs index e8eec2cbb14..43848504a7f 100644 --- a/noir/noir-repo/tooling/profiler/src/fs.rs +++ b/noir/noir-repo/tooling/profiler/src/fs.rs @@ -1,6 +1,10 @@ -use std::path::Path; +use std::{collections::BTreeMap, path::Path}; use color_eyre::eyre; +use noirc_abi::{ + input_parser::{Format, InputValue}, + Abi, InputMap, MAIN_RETURN_NAME, +}; use noirc_artifacts::program::ProgramArtifact; pub(crate) fn read_program_from_file>( @@ -13,3 +17,26 @@ pub(crate) fn read_program_from_file>( Ok(program) } + +/// Returns the circuit's parameters and its return value, if one exists. +/// # Examples +/// +/// ```ignore +/// let (input_map, return_value): (InputMap, Option) = +/// read_inputs_from_file(path, "Verifier", Format::Toml, &abi)?; +/// ``` +pub(crate) fn read_inputs_from_file( + file_path: &Path, + format: Format, + abi: &Abi, +) -> eyre::Result<(InputMap, Option)> { + if abi.is_empty() { + return Ok((BTreeMap::new(), None)); + } + + let input_string = std::fs::read_to_string(file_path)?; + let mut input_map = format.parse(&input_string, abi)?; + let return_value = input_map.remove(MAIN_RETURN_NAME); + + Ok((input_map, return_value)) +} diff --git a/noir/noir-repo/yarn.lock b/noir/noir-repo/yarn.lock index 03cea21026e..b39f9c257c6 100644 --- a/noir/noir-repo/yarn.lock +++ b/noir/noir-repo/yarn.lock @@ -221,9 +221,9 @@ __metadata: languageName: node linkType: hard -"@aztec/bb.js@portal:../../../../barretenberg/ts::locator=integration-tests%40workspace%3Acompiler%2Fintegration-tests": - version: 0.0.0-use.local - resolution: "@aztec/bb.js@portal:../../../../barretenberg/ts::locator=integration-tests%40workspace%3Acompiler%2Fintegration-tests" +"@aztec/bb.js@npm:0.60.0": + version: 0.60.0 + resolution: "@aztec/bb.js@npm:0.60.0" dependencies: comlink: ^4.4.1 commander: ^10.0.1 @@ -231,9 +231,10 @@ __metadata: fflate: ^0.8.0 tslib: ^2.4.0 bin: - bb.js: ./dest/node/main.js + bb.js: dest/node/main.js + checksum: 74ab79d060624362e9d44dda11dc2445973460577b93dc0c16801158db7efb71cd612966d6169b46bfbbb4fd7c9c1b95ad8b6198b3c69d9f6de0ab0fb92387aa languageName: node - linkType: soft + linkType: hard "@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.11, @babel/code-frame@npm:^7.16.0, @babel/code-frame@npm:^7.22.13, @babel/code-frame@npm:^7.23.5, @babel/code-frame@npm:^7.8.3": version: 7.23.5 @@ -14122,7 +14123,7 @@ __metadata: version: 0.0.0-use.local resolution: "integration-tests@workspace:compiler/integration-tests" dependencies: - "@aztec/bb.js": "portal:../../../../barretenberg/ts" + "@aztec/bb.js": 0.60.0 "@noir-lang/noir_js": "workspace:*" "@noir-lang/noir_wasm": "workspace:*" "@nomicfoundation/hardhat-chai-matchers": ^2.0.0