From 8763204619b1ea09716e3cfaedb1303c96ae953a Mon Sep 17 00:00:00 2001 From: fcarreiro Date: Thu, 26 Sep 2024 14:39:16 +0000 Subject: [PATCH 1/7] done --- avm-transpiler/src/transpile_contract.rs | 4 +- .../aztec-nr/aztec/src/macros/dispatch/mod.nr | 141 ++++++++++++++++++ .../aztec-nr/aztec/src/macros/mod.nr | 7 +- .../crates/types/src/traits.nr | 10 +- .../crates/types/src/type_serialization.nr | 30 +++- 5 files changed, 177 insertions(+), 15 deletions(-) create mode 100644 noir-projects/aztec-nr/aztec/src/macros/dispatch/mod.nr diff --git a/avm-transpiler/src/transpile_contract.rs b/avm-transpiler/src/transpile_contract.rs index 542baef9cc72..12f5e5ce0893 100644 --- a/avm-transpiler/src/transpile_contract.rs +++ b/avm-transpiler/src/transpile_contract.rs @@ -92,7 +92,9 @@ impl From for TranspiledContractArtifact { for function in contract.functions { // TODO(4269): once functions are tagged for transpilation to AVM, check tag - if function.custom_attributes.contains(&"public".to_string()) { + if function.custom_attributes.contains(&"public".to_string()) + || function.name == "public_dispatch" + { info!("Transpiling AVM function {} on contract {}", function.name, contract.name); // Extract Brillig Opcodes from acir let acir_program = function.bytecode; diff --git a/noir-projects/aztec-nr/aztec/src/macros/dispatch/mod.nr b/noir-projects/aztec-nr/aztec/src/macros/dispatch/mod.nr new file mode 100644 index 000000000000..1c677fef68c1 --- /dev/null +++ b/noir-projects/aztec-nr/aztec/src/macros/dispatch/mod.nr @@ -0,0 +1,141 @@ +use super::utils::compute_fn_selector; + +/// Returns an `fn public_dispatch(...)` function for the given module that's assumed to be an Aztec contract. +pub comptime fn generate_public_dispatch(m: Module) -> Quoted { + let functions = m.functions(); + let functions = functions.filter(|function: FunctionDefinition| function.has_named_attribute("public")); + + let unit = get_type::<()>(); + + let ifs = functions.map( + |function: FunctionDefinition| { + let name = function.name(); + let parameters = function.parameters(); + let return_type = function.return_type(); + + let selector: Field = compute_fn_selector(function); + + let mut parameters_size = 0; + for param in parameters { + parameters_size += size_in_fields(param.1); + } + + let initial_read = if parameters.len() == 0 { + quote {} + } else { + // The initial calldata_copy offset is 1 to skip the Field selector + quote { + let input_calldata: [Field; $parameters_size] = dep::aztec::context::public_context::calldata_copy(1, $parameters_size); + let mut reader = dep::aztec::protocol_types::utils::reader::Reader::new(input_calldata); + } + }; + + let mut parameter_index = 0; + let reads = parameters.map(|param: (Quoted, Type)| { + let param_name = f"arg{parameter_index}".quoted_contents(); + let param_type = param.1; + let read = quote { + let $param_name: $param_type = reader.read_struct(dep::aztec::protocol_types::traits::Deserialize::deserialize); + }; + parameter_index += 1; + quote { $read } + }); + let read = reads.join(quote { }); + + let mut args = &[]; + for parameter_index in 0..parameters.len() { + let param_name = f"arg{parameter_index}".quoted_contents(); + args = args.push_back(quote { $param_name }); + } + + let args = args.join(quote { , }); + let call = quote { $name($args) }; + + let return_code = if return_type == unit { + quote { $call } + } else { + quote { + let return_value = dep::aztec::protocol_types::traits::Serialize::serialize($call); + dep::aztec::context::public_context::avm_return(return_value); + } + }; + + let if_ = quote { + if selector == $selector { + $initial_read + $read + $return_code + } + }; + if_ + } + ); + + if ifs.len() == 0 { + // No dispatch function if there are no public functions + quote {} + } else { + let ifs = ifs.push_back(quote { { panic(f"Unknown selector") } }); + let dispatch = ifs.join(quote { else }); + + let body = quote { + unconstrained pub fn public_dispatch(selector: Field) { + $dispatch + } + }; + + body + } +} + +comptime fn size_in_fields(typ: Type) -> u32 { + if typ.as_slice().is_some() { + panic(f"Can't determine size in fields of Slice type") + } else { + let size = array_size_in_fields(typ); + let size = size.or_else(|| struct_size_in_fields(typ)); + let size = size.or_else(|| tuple_size_in_fields(typ)); + size.unwrap_or(1) + } +} + +comptime fn array_size_in_fields(typ: Type) -> Option { + typ.as_array().and_then( + |typ: (Type, Type)| { + let (typ, element_size) = typ; + element_size.as_constant().map(|x: u32| { + x * size_in_fields(typ) + }) + } + ) +} + +comptime fn struct_size_in_fields(typ: Type) -> Option { + typ.as_struct().map( + |typ: (StructDefinition, [Type])| { + let struct_type = typ.0; + let mut size = 0; + for field in struct_type.fields() { + size += size_in_fields(field.1); + } + size + } + ) +} + +comptime fn tuple_size_in_fields(typ: Type) -> Option { + typ.as_tuple().map( + |types: [Type]| { + let mut size = 0; + for typ in types { + size += size_in_fields(typ); + } + size + } + ) +} + +comptime fn get_type() -> Type { + let t: T = std::mem::zeroed(); + std::meta::type_of(t) +} diff --git a/noir-projects/aztec-nr/aztec/src/macros/mod.nr b/noir-projects/aztec-nr/aztec/src/macros/mod.nr index 23da22f2d1d5..df5a1530f12f 100644 --- a/noir-projects/aztec-nr/aztec/src/macros/mod.nr +++ b/noir-projects/aztec-nr/aztec/src/macros/mod.nr @@ -1,3 +1,4 @@ +mod dispatch; mod functions; mod utils; mod notes; @@ -10,26 +11,26 @@ use notes::{NOTES, generate_note_export}; use functions::transform_unconstrained; use utils::module_has_storage; +use dispatch::generate_public_dispatch; /// Marks a contract as an Aztec contract, generating the interfaces for its functions and notes, as well as injecting /// the `compute_note_hash_and_optionally_a_nullifier` function PXE requires in order to validate notes. pub comptime fn aztec(m: Module) -> Quoted { let interface = generate_contract_interface(m); - let unconstrained_functions = m.functions().filter( | f: FunctionDefinition | f.is_unconstrained() & !f.has_named_attribute("test") & !f.has_named_attribute("public") ); for f in unconstrained_functions { transform_unconstrained(f); } - let compute_note_hash_and_optionally_a_nullifier = generate_compute_note_hash_and_optionally_a_nullifier(); let note_exports = generate_note_exports(); - + let public_dispatch = generate_public_dispatch(m); quote { $note_exports $interface $compute_note_hash_and_optionally_a_nullifier + $public_dispatch } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/traits.nr b/noir-projects/noir-protocol-circuits/crates/types/src/traits.nr index 8b287d4177ab..60a3c6031b30 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/traits.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/traits.nr @@ -155,12 +155,6 @@ pub trait Serialize { } // docs:end:serialize -impl Serialize for [Field; N] { - fn serialize(self) -> [Field; N] { - self - } -} - impl Serialize for str { fn serialize(self) -> [Field; N] { let bytes = self.as_bytes(); @@ -179,8 +173,8 @@ pub trait Deserialize { } // docs:end:deserialize -impl Deserialize for [Field; N] { +impl Deserialize for str { fn deserialize(fields: [Field; N]) -> Self { - fields + str::from(fields.map(|value| value as u8)) } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/type_serialization.nr b/noir-projects/noir-protocol-circuits/crates/types/src/type_serialization.nr index ac113fe2f794..8e9bf06a82bd 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/type_serialization.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/type_serialization.nr @@ -20,7 +20,7 @@ impl Deserialize for bool { } impl Serialize for u8 { - fn serialize(self) -> [Field; U32_SERIALIZED_LEN] { + fn serialize(self) -> [Field; U8_SERIALIZED_LEN] { [self as Field] } } @@ -56,7 +56,7 @@ impl Deserialize for u64 { } impl Serialize for U128 { - fn serialize(self) -> [Field; 1] { + fn serialize(self) -> [Field; U128_SERIALIZED_LEN] { [self.to_integer()] } } @@ -68,7 +68,7 @@ impl Deserialize for U128 { } impl Serialize for Field { - fn serialize(self) -> [Field; U32_SERIALIZED_LEN] { + fn serialize(self) -> [Field; FIELD_SERIALIZED_LEN] { [self] } } @@ -78,3 +78,27 @@ impl Deserialize for Field { fields[0] } } + +impl Serialize for [T; N] where T: Serialize { + fn serialize(self) -> [Field; N * M] { + let mut result: [Field; N * M] = std::mem::zeroed(); + let mut serialized: [Field; M] = std::mem::zeroed(); + let mut offset = 0; + for i in 0..N { + serialized = self[i].serialize(); + for j in 0..M { + result[offset] = serialized[j]; + offset += 1; + } + } + result + } +} + +impl Deserialize for [T; N] where T: Deserialize{ + fn deserialize(fields: [Field; N * M]) -> Self { + let mut reader = crate::utils::reader::Reader::new(fields); + let mut result: [T; N] = std::mem::zeroed(); + reader.read_struct_array::(Deserialize::deserialize, result) + } +} \ No newline at end of file From 611f8ba06b1988ec06176bc31ca61ba5878066f8 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Thu, 26 Sep 2024 12:19:14 -0300 Subject: [PATCH 2/7] Don't use if-else in dispatch --- avm-transpiler/src/transpile_contract.rs | 1 - noir-projects/aztec-nr/aztec/src/macros/dispatch/mod.nr | 4 ++-- .../crates/types/src/type_serialization.nr | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/avm-transpiler/src/transpile_contract.rs b/avm-transpiler/src/transpile_contract.rs index 12f5e5ce0893..b08d817026fe 100644 --- a/avm-transpiler/src/transpile_contract.rs +++ b/avm-transpiler/src/transpile_contract.rs @@ -91,7 +91,6 @@ impl From for TranspiledContractArtifact { let mut functions: Vec = Vec::new(); for function in contract.functions { - // TODO(4269): once functions are tagged for transpilation to AVM, check tag if function.custom_attributes.contains(&"public".to_string()) || function.name == "public_dispatch" { diff --git a/noir-projects/aztec-nr/aztec/src/macros/dispatch/mod.nr b/noir-projects/aztec-nr/aztec/src/macros/dispatch/mod.nr index 1c677fef68c1..db179e2a41ce 100644 --- a/noir-projects/aztec-nr/aztec/src/macros/dispatch/mod.nr +++ b/noir-projects/aztec-nr/aztec/src/macros/dispatch/mod.nr @@ -75,8 +75,8 @@ pub comptime fn generate_public_dispatch(m: Module) -> Quoted { // No dispatch function if there are no public functions quote {} } else { - let ifs = ifs.push_back(quote { { panic(f"Unknown selector") } }); - let dispatch = ifs.join(quote { else }); + let ifs = ifs.push_back(quote { panic(f"Unknown selector") }); + let dispatch = ifs.join(quote { }); let body = quote { unconstrained pub fn public_dispatch(selector: Field) { diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/type_serialization.nr b/noir-projects/noir-protocol-circuits/crates/types/src/type_serialization.nr index 8e9bf06a82bd..703626cd50a6 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/type_serialization.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/type_serialization.nr @@ -95,10 +95,10 @@ impl Serialize for [T; N] where T: Serialize< } } -impl Deserialize for [T; N] where T: Deserialize{ +impl Deserialize for [T; N] where T: Deserialize { fn deserialize(fields: [Field; N * M]) -> Self { let mut reader = crate::utils::reader::Reader::new(fields); let mut result: [T; N] = std::mem::zeroed(); reader.read_struct_array::(Deserialize::deserialize, result) } -} \ No newline at end of file +} From a5a8d28176aa5474c5862497b12d9c2ad96d2d72 Mon Sep 17 00:00:00 2001 From: fcarreiro Date: Thu, 26 Sep 2024 15:42:07 +0000 Subject: [PATCH 3/7] include dispatch in report --- .../publicFunctionsSizeReport.js | 61 ++++++++++--------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/noir-projects/noir-contracts/publicFunctionsSizeReport.js b/noir-projects/noir-contracts/publicFunctionsSizeReport.js index 9324690bd24b..e8c2fde467ba 100644 --- a/noir-projects/noir-contracts/publicFunctionsSizeReport.js +++ b/noir-projects/noir-contracts/publicFunctionsSizeReport.js @@ -8,7 +8,6 @@ const fsp = require("fs").promises; // However, this script was made to re-use the noir-gates-diff for bytecode sizes as // to minimize both the amount of changes needed in noir-gates-diff and in nargo. async function main() { - let [targetDir] = process.argv.slice(2); if (!targetDir) { console.log( @@ -18,46 +17,48 @@ async function main() { } let artifactPaths = []; - fs.readdirSync(targetDir).forEach(file => { + fs.readdirSync(targetDir).forEach((file) => { // We want to exclude any backups that may be generated by the avm-transpiler if (path.extname(file) === ".json") { - artifactPaths.push(path.join(targetDir, file)); + artifactPaths.push(path.join(targetDir, file)); } }); let workspaceReport = { - programs: [] - } + programs: [], + }; for (var i = 0; i < artifactPaths.length; i++) { let contractArtifactPath = artifactPaths[i]; const contractArtifact = JSON.parse( - await fsp.readFile(contractArtifactPath, "utf8") + await fsp.readFile(contractArtifactPath, "utf8") ); - contractArtifact.functions.forEach(async func => { - if (func.custom_attributes.includes("public")) { - if (func.brillig_names.length != 1) { - console.log( - "Expected only a single Brillig function" - ); - return; - } - let func_with_contract_name = contractArtifact.name + "::" + func.brillig_names[0]; - let program_report = { - package_name: "", - functions: [{ name: "main", opcodes: 1 }], - unconstrained_functions: [], - } - // Programs are compared by package name, so we make a unique one for each function here - program_report.package_name = func_with_contract_name; - let bytecode_bytes = Buffer.from(func.bytecode, 'base64'); - let func_report = { - name: "main", - opcodes: bytecode_bytes, - }; - func_report.opcodes = bytecode_bytes.length; - program_report.unconstrained_functions.push(func_report); - workspaceReport.programs.push(program_report); + contractArtifact.functions.forEach(async (func) => { + if ( + func.custom_attributes.includes("public") || + func.name === "public_dispatch" + ) { + if (func.brillig_names.length != 1) { + console.log("Expected only a single Brillig function"); + return; } + let func_with_contract_name = + contractArtifact.name + "::" + func.brillig_names[0]; + let program_report = { + package_name: "", + functions: [{ name: "main", opcodes: 1 }], + unconstrained_functions: [], + }; + // Programs are compared by package name, so we make a unique one for each function here + program_report.package_name = func_with_contract_name; + let bytecode_bytes = Buffer.from(func.bytecode, "base64"); + let func_report = { + name: "main", + opcodes: bytecode_bytes, + }; + func_report.opcodes = bytecode_bytes.length; + program_report.unconstrained_functions.push(func_report); + workspaceReport.programs.push(program_report); + } }); } From 3665c84dacec8da74d92db5d0068eb038f4ccda4 Mon Sep 17 00:00:00 2001 From: fcarreiro Date: Thu, 26 Sep 2024 16:35:32 +0000 Subject: [PATCH 4/7] address changes --- .../aztec-nr/aztec/src/macros/dispatch/mod.nr | 37 +++++++++++-------- .../crates/types/src/type_serialization.nr | 4 +- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/macros/dispatch/mod.nr b/noir-projects/aztec-nr/aztec/src/macros/dispatch/mod.nr index db179e2a41ce..580a71b27a59 100644 --- a/noir-projects/aztec-nr/aztec/src/macros/dispatch/mod.nr +++ b/noir-projects/aztec-nr/aztec/src/macros/dispatch/mod.nr @@ -24,6 +24,11 @@ pub comptime fn generate_public_dispatch(m: Module) -> Quoted { quote {} } else { // The initial calldata_copy offset is 1 to skip the Field selector + // The expected calldata is the serialization of + // - FunctionSelector: the selector of the function intended to dispatch + // - Parameters: the parameters of the function intended to dispatch + // That is, exactly what is expected for a call to the target function, + // but with a selector added at the beginning. quote { let input_calldata: [Field; $parameters_size] = dep::aztec::context::public_context::calldata_copy(1, $parameters_size); let mut reader = dep::aztec::protocol_types::utils::reader::Reader::new(input_calldata); @@ -102,36 +107,36 @@ comptime fn size_in_fields(typ: Type) -> u32 { comptime fn array_size_in_fields(typ: Type) -> Option { typ.as_array().and_then( |typ: (Type, Type)| { - let (typ, element_size) = typ; - element_size.as_constant().map(|x: u32| { - x * size_in_fields(typ) - }) - } + let (typ, element_size) = typ; + element_size.as_constant().map(|x: u32| { + x * size_in_fields(typ) + }) + } ) } comptime fn struct_size_in_fields(typ: Type) -> Option { typ.as_struct().map( |typ: (StructDefinition, [Type])| { - let struct_type = typ.0; - let mut size = 0; - for field in struct_type.fields() { - size += size_in_fields(field.1); + let struct_type = typ.0; + let mut size = 0; + for field in struct_type.fields() { + size += size_in_fields(field.1); + } + size } - size - } ) } comptime fn tuple_size_in_fields(typ: Type) -> Option { typ.as_tuple().map( |types: [Type]| { - let mut size = 0; - for typ in types { - size += size_in_fields(typ); + let mut size = 0; + for typ in types { + size += size_in_fields(typ); + } + size } - size - } ) } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/type_serialization.nr b/noir-projects/noir-protocol-circuits/crates/types/src/type_serialization.nr index 703626cd50a6..59d9fad56280 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/type_serialization.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/type_serialization.nr @@ -83,12 +83,10 @@ impl Serialize for [T; N] where T: Serialize< fn serialize(self) -> [Field; N * M] { let mut result: [Field; N * M] = std::mem::zeroed(); let mut serialized: [Field; M] = std::mem::zeroed(); - let mut offset = 0; for i in 0..N { serialized = self[i].serialize(); for j in 0..M { - result[offset] = serialized[j]; - offset += 1; + result[i * M + j] = serialized[j]; } } result From 797353e177a5ddb2ad1440196c62bb169a807550 Mon Sep 17 00:00:00 2001 From: fcarreiro Date: Thu, 26 Sep 2024 17:00:02 +0000 Subject: [PATCH 5/7] fix void early return --- noir-projects/aztec-nr/aztec/src/macros/dispatch/mod.nr | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/noir-projects/aztec-nr/aztec/src/macros/dispatch/mod.nr b/noir-projects/aztec-nr/aztec/src/macros/dispatch/mod.nr index 580a71b27a59..884ac14fa721 100644 --- a/noir-projects/aztec-nr/aztec/src/macros/dispatch/mod.nr +++ b/noir-projects/aztec-nr/aztec/src/macros/dispatch/mod.nr @@ -57,7 +57,11 @@ pub comptime fn generate_public_dispatch(m: Module) -> Quoted { let call = quote { $name($args) }; let return_code = if return_type == unit { - quote { $call } + quote { + $call; + // Force early return. + dep::aztec::context::public_context::avm_return([]); + } } else { quote { let return_value = dep::aztec::protocol_types::traits::Serialize::serialize($call); From 0c6a711cfc067d5d35a8e6b305f405c531d49065 Mon Sep 17 00:00:00 2001 From: fcarreiro Date: Fri, 27 Sep 2024 09:39:52 +0000 Subject: [PATCH 6/7] mark dispatch as public --- avm-transpiler/src/transpile_contract.rs | 4 +--- noir-projects/aztec-nr/aztec/src/macros/dispatch/mod.nr | 4 ++++ noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr | 9 +++++++++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/avm-transpiler/src/transpile_contract.rs b/avm-transpiler/src/transpile_contract.rs index b08d817026fe..10b9367a4abd 100644 --- a/avm-transpiler/src/transpile_contract.rs +++ b/avm-transpiler/src/transpile_contract.rs @@ -91,9 +91,7 @@ impl From for TranspiledContractArtifact { let mut functions: Vec = Vec::new(); for function in contract.functions { - if function.custom_attributes.contains(&"public".to_string()) - || function.name == "public_dispatch" - { + if function.custom_attributes.contains(&"public".to_string()) { info!("Transpiling AVM function {} on contract {}", function.name, contract.name); // Extract Brillig Opcodes from acir let acir_program = function.bytecode; diff --git a/noir-projects/aztec-nr/aztec/src/macros/dispatch/mod.nr b/noir-projects/aztec-nr/aztec/src/macros/dispatch/mod.nr index 884ac14fa721..f7e962241306 100644 --- a/noir-projects/aztec-nr/aztec/src/macros/dispatch/mod.nr +++ b/noir-projects/aztec-nr/aztec/src/macros/dispatch/mod.nr @@ -88,6 +88,10 @@ pub comptime fn generate_public_dispatch(m: Module) -> Quoted { let dispatch = ifs.join(quote { }); let body = quote { + // We mark this as public because our whole system depends on public + // functions having this attribute. However, the public MACRO will + // handle the public_dispatch function specially and do nothing. + #[public] unconstrained pub fn public_dispatch(selector: Field) { $dispatch } diff --git a/noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr b/noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr index 2b5768278819..1fc42fbab76b 100644 --- a/noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr +++ b/noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr @@ -225,6 +225,15 @@ pub comptime fn private(f: FunctionDefinition) -> Quoted { /// Public functions are executed sequencer-side and do not preserve privacy, similar to the EVM. pub comptime fn public(f: FunctionDefinition) -> Quoted { + // We don't want to transform the public_dispatch function. + if f.name() == quote { public_dispatch } { + quote {} + } else { + transform_public(f) + } +} + +comptime fn transform_public(f: FunctionDefinition) -> Quoted { let fn_abi = create_fn_abi_export(f); let fn_stub = stub_fn(f); register_stub(f.module(), fn_stub); From cc5b6044114a1a7720fd7a20f683ff820790262d Mon Sep 17 00:00:00 2001 From: fcarreiro Date: Fri, 27 Sep 2024 09:39:57 +0000 Subject: [PATCH 7/7] Revert "include dispatch in report" This reverts commit a5a8d28176aa5474c5862497b12d9c2ad96d2d72. --- .../publicFunctionsSizeReport.js | 61 +++++++++---------- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/noir-projects/noir-contracts/publicFunctionsSizeReport.js b/noir-projects/noir-contracts/publicFunctionsSizeReport.js index e8c2fde467ba..9324690bd24b 100644 --- a/noir-projects/noir-contracts/publicFunctionsSizeReport.js +++ b/noir-projects/noir-contracts/publicFunctionsSizeReport.js @@ -8,6 +8,7 @@ const fsp = require("fs").promises; // However, this script was made to re-use the noir-gates-diff for bytecode sizes as // to minimize both the amount of changes needed in noir-gates-diff and in nargo. async function main() { + let [targetDir] = process.argv.slice(2); if (!targetDir) { console.log( @@ -17,48 +18,46 @@ async function main() { } let artifactPaths = []; - fs.readdirSync(targetDir).forEach((file) => { + fs.readdirSync(targetDir).forEach(file => { // We want to exclude any backups that may be generated by the avm-transpiler if (path.extname(file) === ".json") { - artifactPaths.push(path.join(targetDir, file)); + artifactPaths.push(path.join(targetDir, file)); } }); let workspaceReport = { - programs: [], - }; + programs: [] + } for (var i = 0; i < artifactPaths.length; i++) { let contractArtifactPath = artifactPaths[i]; const contractArtifact = JSON.parse( - await fsp.readFile(contractArtifactPath, "utf8") + await fsp.readFile(contractArtifactPath, "utf8") ); - contractArtifact.functions.forEach(async (func) => { - if ( - func.custom_attributes.includes("public") || - func.name === "public_dispatch" - ) { - if (func.brillig_names.length != 1) { - console.log("Expected only a single Brillig function"); - return; + contractArtifact.functions.forEach(async func => { + if (func.custom_attributes.includes("public")) { + if (func.brillig_names.length != 1) { + console.log( + "Expected only a single Brillig function" + ); + return; + } + let func_with_contract_name = contractArtifact.name + "::" + func.brillig_names[0]; + let program_report = { + package_name: "", + functions: [{ name: "main", opcodes: 1 }], + unconstrained_functions: [], + } + // Programs are compared by package name, so we make a unique one for each function here + program_report.package_name = func_with_contract_name; + let bytecode_bytes = Buffer.from(func.bytecode, 'base64'); + let func_report = { + name: "main", + opcodes: bytecode_bytes, + }; + func_report.opcodes = bytecode_bytes.length; + program_report.unconstrained_functions.push(func_report); + workspaceReport.programs.push(program_report); } - let func_with_contract_name = - contractArtifact.name + "::" + func.brillig_names[0]; - let program_report = { - package_name: "", - functions: [{ name: "main", opcodes: 1 }], - unconstrained_functions: [], - }; - // Programs are compared by package name, so we make a unique one for each function here - program_report.package_name = func_with_contract_name; - let bytecode_bytes = Buffer.from(func.bytecode, "base64"); - let func_report = { - name: "main", - opcodes: bytecode_bytes, - }; - func_report.opcodes = bytecode_bytes.length; - program_report.unconstrained_functions.push(func_report); - workspaceReport.programs.push(program_report); - } }); }