diff --git a/Cargo.lock b/Cargo.lock index 1538bed2fb5..da6ac2b91e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,7 +10,6 @@ dependencies = [ "bincode", "brillig", "flate2", - "rmp-serde", "serde", "serde_json", "strum", @@ -3122,28 +3121,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "rmp" -version = "0.8.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9860a6cc38ed1da53456442089b4dfa35e7cedaa326df63017af88385e6b20" -dependencies = [ - "byteorder", - "num-traits", - "paste", -] - -[[package]] -name = "rmp-serde" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bffea85eea980d8a74453e5d02a8d93028f3c34725de143085a844ebe953258a" -dependencies = [ - "byteorder", - "rmp", - "serde", -] - [[package]] name = "rust-embed" version = "6.8.1" diff --git a/acvm-repo/acir/Cargo.toml b/acvm-repo/acir/Cargo.toml index f4bdd72e25a..a7c55b3d8ac 100644 --- a/acvm-repo/acir/Cargo.toml +++ b/acvm-repo/acir/Cargo.toml @@ -17,7 +17,6 @@ acir_field.workspace = true brillig.workspace = true serde.workspace = true thiserror.workspace = true -rmp-serde = { version = "1.1.0", optional = true } flate2 = "1.0.24" bincode.workspace = true @@ -30,4 +29,3 @@ strum_macros = "0.24" default = ["bn254"] bn254 = ["acir_field/bn254", "brillig/bn254"] bls12_381 = ["acir_field/bls12_381", "brillig/bls12_381"] -serialize-messagepack = ["rmp-serde"] diff --git a/acvm-repo/acir/src/circuit/mod.rs b/acvm-repo/acir/src/circuit/mod.rs index d03240af2c3..eef5a5fb6bc 100644 --- a/acvm-repo/acir/src/circuit/mod.rs +++ b/acvm-repo/acir/src/circuit/mod.rs @@ -125,24 +125,6 @@ impl Circuit { PublicInputs(public_inputs) } - #[cfg(feature = "serialize-messagepack")] - pub fn write(&self, writer: W) -> std::io::Result<()> { - let buf = rmp_serde::to_vec(&self).unwrap(); - let mut deflater = flate2::write::DeflateEncoder::new(writer, Compression::best()); - deflater.write_all(&buf).unwrap(); - - Ok(()) - } - #[cfg(feature = "serialize-messagepack")] - pub fn read(reader: R) -> std::io::Result { - let mut deflater = flate2::read::DeflateDecoder::new(reader); - let mut buf_d = Vec::new(); - deflater.read_to_end(&mut buf_d).unwrap(); - let circuit = rmp_serde::from_slice(buf_d.as_slice()).unwrap(); - Ok(circuit) - } - - #[cfg(not(feature = "serialize-messagepack"))] pub fn write(&self, writer: W) -> std::io::Result<()> { let buf = bincode::serialize(&self).unwrap(); let mut encoder = flate2::write::GzEncoder::new(writer, Compression::default()); @@ -151,7 +133,6 @@ impl Circuit { Ok(()) } - #[cfg(not(feature = "serialize-messagepack"))] pub fn read(reader: R) -> std::io::Result { let mut gz_decoder = flate2::read::GzDecoder::new(reader); let mut buf_d = Vec::new(); diff --git a/acvm-repo/acir/src/native_types/witness_map.rs b/acvm-repo/acir/src/native_types/witness_map.rs index 400e0a8ca1a..1734b0b907f 100644 --- a/acvm-repo/acir/src/native_types/witness_map.rs +++ b/acvm-repo/acir/src/native_types/witness_map.rs @@ -13,20 +13,6 @@ use thiserror::Error; use crate::native_types::Witness; -#[cfg(feature = "serialize-messagepack")] -#[derive(Debug, Error)] -enum SerializationError { - #[error(transparent)] - MsgpackEncode(#[from] rmp_serde::encode::Error), - - #[error(transparent)] - MsgpackDecode(#[from] rmp_serde::decode::Error), - - #[error(transparent)] - Deflate(#[from] std::io::Error), -} - -#[cfg(not(feature = "serialize-messagepack"))] #[derive(Debug, Error)] enum SerializationError { #[error(transparent)] @@ -92,20 +78,6 @@ impl From> for WitnessMap { } } -#[cfg(feature = "serialize-messagepack")] -impl TryFrom for Vec { - type Error = WitnessMapError; - - fn try_from(val: WitnessMap) -> Result { - let buf = rmp_serde::to_vec(&val).map_err(|err| WitnessMapError(err.into()))?; - let mut deflater = flate2::write::DeflateEncoder::new(buf.as_slice(), Compression::best()); - let mut buf_c = Vec::new(); - deflater.read_to_end(&mut buf_c).map_err(|err| WitnessMapError(err.into()))?; - Ok(buf_c) - } -} - -#[cfg(not(feature = "serialize-messagepack"))] impl TryFrom for Vec { type Error = WitnessMapError; @@ -118,21 +90,6 @@ impl TryFrom for Vec { } } -#[cfg(feature = "serialize-messagepack")] -impl TryFrom<&[u8]> for WitnessMap { - type Error = WitnessMapError; - - fn try_from(bytes: &[u8]) -> Result { - let mut deflater = flate2::bufread::DeflateDecoder::new(bytes); - let mut buf_d = Vec::new(); - deflater.read_to_end(&mut buf_d).map_err(|err| WitnessMapError(err.into()))?; - let witness_map = - rmp_serde::from_slice(buf_d.as_slice()).map_err(|err| WitnessMapError(err.into()))?; - Ok(Self(witness_map)) - } -} - -#[cfg(not(feature = "serialize-messagepack"))] impl TryFrom<&[u8]> for WitnessMap { type Error = WitnessMapError; diff --git a/acvm-repo/acvm_js/package.json b/acvm-repo/acvm_js/package.json index 27ae5dd3fbf..990ce0de7ef 100644 --- a/acvm-repo/acvm_js/package.json +++ b/acvm-repo/acvm_js/package.json @@ -27,7 +27,8 @@ "build": "bash ./build.sh", "test": "env TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\" }' mocha", "test:browser": "web-test-runner", - "lint": "NODE_NO_WARNINGS=1 eslint . --ext .ts --ignore-path ./.eslintignore --max-warnings 0" + "lint": "NODE_NO_WARNINGS=1 eslint . --ext .ts --ignore-path ./.eslintignore --max-warnings 0", + "clean": "chmod u+w web nodejs && rm -rf web nodejs" }, "devDependencies": { "@esm-bundle/chai": "^4.3.4-fix.0", diff --git a/compiler/noirc_driver/src/contract.rs b/compiler/noirc_driver/src/contract.rs index 69a92764318..a16da313ff6 100644 --- a/compiler/noirc_driver/src/contract.rs +++ b/compiler/noirc_driver/src/contract.rs @@ -3,7 +3,7 @@ use std::collections::BTreeMap; use acvm::acir::circuit::Circuit; use fm::FileId; -use noirc_abi::Abi; +use noirc_abi::{Abi, ContractEvent}; use noirc_errors::debug_info::DebugInfo; use super::debug::DebugFile; @@ -34,6 +34,11 @@ pub struct CompiledContract { /// stored in this `Vector`. pub functions: Vec, + /// All the events defined inside the contract scope. + /// An event is a struct value that can be emitted via oracles + /// by any contract function during execution. + pub events: Vec, + pub file_map: BTreeMap, } diff --git a/compiler/noirc_driver/src/lib.rs b/compiler/noirc_driver/src/lib.rs index 60073f9cc84..381a29ffcda 100644 --- a/compiler/noirc_driver/src/lib.rs +++ b/compiler/noirc_driver/src/lib.rs @@ -6,7 +6,7 @@ use clap::Args; use debug::filter_relevant_files; use fm::FileId; -use noirc_abi::{AbiParameter, AbiType}; +use noirc_abi::{AbiParameter, AbiType, ContractEvent}; use noirc_errors::{CustomDiagnostic, FileDiagnostic}; use noirc_evaluator::{create_circuit, into_abi_params}; use noirc_frontend::graph::{CrateId, CrateName}; @@ -285,7 +285,20 @@ fn compile_contract_inner( let debug_infos: Vec<_> = functions.iter().map(|function| function.debug.clone()).collect(); let file_map = filter_relevant_files(&debug_infos, &context.file_manager); - Ok(CompiledContract { name: contract.name, functions, file_map }) + Ok(CompiledContract { + name: contract.name, + events: contract + .events + .iter() + .map(|event_id| { + let typ = context.def_interner.get_struct(*event_id); + let typ = typ.borrow(); + ContractEvent::from_struct_type(context, &typ) + }) + .collect(), + functions, + file_map, + }) } else { Err(errors) } diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs index 8e6237a40f4..a2a85498f16 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs @@ -596,10 +596,12 @@ impl GeneratedAcir { // we now have lhs+offset <= rhs <=> lhs_offset <= rhs_offset let bit_size = bit_size_u128(rhs_offset); - // r = 2^bit_size - rhs_offset + // r = 2^bit_size - rhs_offset -1, is of bit size 'bit_size' by construtction let r = (1_u128 << bit_size) - rhs_offset - 1; + // however, since it is a constant, we can compute it's actual bit size + let r_bit_size = bit_size_u128(r); // witness = lhs_offset + r - assert!(bits + bit_size < FieldElement::max_num_bits()); //we need to ensure lhs_offset + r does not overflow + assert!(bits + r_bit_size < FieldElement::max_num_bits()); //we need to ensure lhs_offset + r does not overflow let mut aor = lhs_offset; aor.q_c += FieldElement::from(r); let witness = self.get_or_create_witness(&aor); @@ -607,7 +609,6 @@ impl GeneratedAcir { self.range_constraint(witness, bit_size)?; return Ok(()); } - // General case: lhs_offset<=rhs <=> rhs-lhs_offset>=0 <=> rhs-lhs_offset is a 'bits' bit integer let sub_expression = rhs - &lhs_offset; //rhs-lhs_offset let w = self.create_witness_for_expression(&sub_expression); diff --git a/compiler/noirc_frontend/src/hir/def_map/mod.rs b/compiler/noirc_frontend/src/hir/def_map/mod.rs index 4226454f903..27f757074f6 100644 --- a/compiler/noirc_frontend/src/hir/def_map/mod.rs +++ b/compiler/noirc_frontend/src/hir/def_map/mod.rs @@ -1,9 +1,9 @@ use crate::graph::CrateId; use crate::hir::def_collector::dc_crate::{CompilationError, DefCollector}; use crate::hir::Context; -use crate::node_interner::{FuncId, NodeInterner}; +use crate::node_interner::{FuncId, NodeInterner, StructId}; use crate::parser::{parse_program, ParsedModule, ParserError}; -use crate::token::{FunctionAttribute, TestScope}; +use crate::token::{FunctionAttribute, SecondaryAttribute, TestScope}; use arena::{Arena, Index}; use fm::{FileId, FileManager}; use noirc_errors::Location; @@ -182,8 +182,20 @@ impl CrateDefMap { }) .collect(); + let events = module + .type_definitions() + .filter_map(|id| { + id.as_type().filter(|struct_id| { + interner + .struct_attributes(struct_id) + .iter() + .any(|attr| attr == &SecondaryAttribute::Event) + }) + }) + .collect(); + let name = self.get_module_path(id, module.parent); - Some(Contract { name, location: module.location, functions }) + Some(Contract { name, location: module.location, functions, events }) } else { None } @@ -236,13 +248,14 @@ pub struct ContractFunctionMeta { pub is_entry_point: bool, } -/// A 'contract' in Noir source code with the given name and functions. +/// A 'contract' in Noir source code with a given name, functions and events. /// This is not an AST node, it is just a convenient form to return for CrateDefMap::get_all_contracts. pub struct Contract { /// To keep `name` semi-unique, it is prefixed with the names of parent modules via CrateDefMap::get_module_path pub name: String, pub location: Location, pub functions: Vec, + pub events: Vec, } /// Given a FileId, fetch the File, from the FileManager and parse it's content diff --git a/compiler/noirc_frontend/src/hir/def_map/module_data.rs b/compiler/noirc_frontend/src/hir/def_map/module_data.rs index 1f1fa44108d..f86cce75479 100644 --- a/compiler/noirc_frontend/src/hir/def_map/module_data.rs +++ b/compiler/noirc_frontend/src/hir/def_map/module_data.rs @@ -97,6 +97,10 @@ impl ModuleData { self.scope.find_name(name) } + pub fn type_definitions(&self) -> impl Iterator + '_ { + self.definitions.types().values().map(|(id, _)| *id) + } + /// Return an iterator over all definitions defined within this module, /// excluding any type definitions. pub fn value_definitions(&self) -> impl Iterator + '_ { diff --git a/compiler/noirc_frontend/src/lexer/token.rs b/compiler/noirc_frontend/src/lexer/token.rs index 9eaa4fa75e5..6aabacd8940 100644 --- a/compiler/noirc_frontend/src/lexer/token.rs +++ b/compiler/noirc_frontend/src/lexer/token.rs @@ -467,6 +467,7 @@ impl Attribute { ["contract_library_method"] => { Attribute::Secondary(SecondaryAttribute::ContractLibraryMethod) } + ["event"] => Attribute::Secondary(SecondaryAttribute::Event), ["deprecated", name] => { if !name.starts_with('"') && !name.ends_with('"') { return Err(LexerErrorKind::MalformedFuncAttribute { @@ -544,6 +545,7 @@ pub enum SecondaryAttribute { // is a helper method for a contract and should not be seen as // the entry point. ContractLibraryMethod, + Event, Custom(String), } @@ -556,6 +558,7 @@ impl fmt::Display for SecondaryAttribute { } SecondaryAttribute::Custom(ref k) => write!(f, "#[{k}]"), SecondaryAttribute::ContractLibraryMethod => write!(f, "#[contract_library_method]"), + SecondaryAttribute::Event => write!(f, "#[event]"), } } } @@ -578,6 +581,7 @@ impl AsRef for SecondaryAttribute { SecondaryAttribute::Deprecated(None) => "", SecondaryAttribute::Custom(string) => string, SecondaryAttribute::ContractLibraryMethod => "", + SecondaryAttribute::Event => "", } } } diff --git a/compiler/noirc_frontend/src/node_interner.rs b/compiler/noirc_frontend/src/node_interner.rs index 01633c29178..ce08f3ebec1 100644 --- a/compiler/noirc_frontend/src/node_interner.rs +++ b/compiler/noirc_frontend/src/node_interner.rs @@ -19,7 +19,7 @@ use crate::hir_def::{ function::{FuncMeta, HirFunction}, stmt::HirStatement, }; -use crate::token::Attributes; +use crate::token::{Attributes, SecondaryAttribute}; use crate::{ ContractFunctionType, FunctionDefinition, Generics, Shared, TypeAliasType, TypeBinding, TypeBindings, TypeVariable, TypeVariableId, TypeVariableKind, Visibility, @@ -32,6 +32,8 @@ pub struct TraitImplKey { // pub generics: Generics - TODO } +type StructAttributes = Vec; + /// The node interner is the central storage location of all nodes in Noir's Hir (the /// various node types can be found in hir_def). The interner is also used to collect /// extra information about the Hir, such as the type of each node, information about @@ -73,6 +75,7 @@ pub struct NodeInterner { // methods from impls to the type. structs: HashMap>, + struct_attributes: HashMap, // Type Aliases map. // // Map type aliases to the actual type. @@ -365,6 +368,7 @@ impl Default for NodeInterner { definitions: vec![], id_to_type: HashMap::new(), structs: HashMap::new(), + struct_attributes: HashMap::new(), type_aliases: Vec::new(), traits: HashMap::new(), trait_implementations: HashMap::new(), @@ -456,6 +460,7 @@ impl NodeInterner { let new_struct = StructType::new(struct_id, name, typ.struct_def.span, no_fields, generics); self.structs.insert(struct_id, Shared::new(new_struct)); + self.struct_attributes.insert(struct_id, typ.struct_def.attributes.clone()); struct_id } @@ -678,6 +683,10 @@ impl NodeInterner { &self.function_modifiers[func_id].attributes } + pub fn struct_attributes(&self, struct_id: &StructId) -> &StructAttributes { + &self.struct_attributes[struct_id] + } + /// Returns the interned statement corresponding to `stmt_id` pub fn statement(&self, stmt_id: &StmtId) -> HirStatement { let def = diff --git a/compiler/wasm/package.json b/compiler/wasm/package.json index c4d3a111278..7bab66299b4 100644 --- a/compiler/wasm/package.json +++ b/compiler/wasm/package.json @@ -23,7 +23,7 @@ "test": "env TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\" }' mocha", "test:node": "env TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\" }' mocha", "test:browser": "web-test-runner", - "clean": "rm -rf ./nodejs ./web ./target ./result", + "clean": "chmod u+w web nodejs && rm -rf ./nodejs ./web ./target ./result", "lint": "NODE_NO_WARNINGS=1 eslint . --ext .ts --ignore-path ./.eslintignore --max-warnings 0" }, "peerDependencies": { diff --git a/flake.nix b/flake.nix index 585a0d143d4..8c8371720b4 100644 --- a/flake.nix +++ b/flake.nix @@ -235,6 +235,7 @@ # Nix flakes cannot build more than one derivation in one command (see https://github.com/NixOS/nix/issues/5591) # so we use `symlinkJoin` to build everything as the "all" package. all = pkgs.symlinkJoin { name = "all"; paths = [ nargo noir_wasm noirc_abi_wasm acvm_js ]; }; + all_wasm = pkgs.symlinkJoin { name = "all_wasm"; paths = [ noir_wasm noirc_abi_wasm acvm_js ]; }; # We also export individual packages to enable `nix build .#nargo -L`, etc. inherit nargo; diff --git a/package.json b/package.json index 3e65058bb61..84d44a38383 100644 --- a/package.json +++ b/package.json @@ -19,10 +19,11 @@ "clean:root": "rm -rf ./result ./target", "clean": "yarn clean:workspaces && yarn clean:root", "lint": "yarn workspaces foreach run lint", - "build:with:nix": "nix build -L .#wasm", + "build:with:nix": "nix build -L .#all_wasm", "install:from:nix:noirc_abi_wasm": "cp -r ./result/noirc_abi_wasm/nodejs ./tooling/noirc_abi_wasm && cp -r ./result/noirc_abi_wasm/web ./tooling/noirc_abi_wasm", "install:from:nix:noir_wasm": "cp -r ./result/noir_wasm/nodejs ./compiler/wasm && cp -r ./result/noir_wasm/web ./compiler/wasm", - "install:from:nix": "yarn build:with:nix && yarn install:from:nix:noirc_abi_wasm && yarn install:from:nix:noir_wasm" + "install:from:nix:acvm_js": "cp -rf ./result/acvm_js/nodejs ./acvm-repo/acvm_js && cp -rf ./result/acvm_js/web ./acvm-repo/acvm_js", + "install:from:nix": "yarn build:with:nix && yarn install:from:nix:noirc_abi_wasm && yarn install:from:nix:noir_wasm && yarn install:from:nix:acvm_js" }, "devDependencies": { "@typescript-eslint/eslint-plugin": "^5.59.5", diff --git a/tooling/nargo/src/artifacts/contract.rs b/tooling/nargo/src/artifacts/contract.rs index 4db7d95731e..fa161b63a5b 100644 --- a/tooling/nargo/src/artifacts/contract.rs +++ b/tooling/nargo/src/artifacts/contract.rs @@ -1,5 +1,5 @@ use acvm::acir::circuit::Circuit; -use noirc_abi::Abi; +use noirc_abi::{Abi, ContractEvent}; use noirc_driver::ContractFunctionType; use serde::{Deserialize, Serialize}; @@ -16,6 +16,8 @@ pub struct PreprocessedContract { pub backend: String, /// Each of the contract's functions are compiled into a separate program stored in this `Vec`. pub functions: Vec, + /// All the events defined inside the contract scope. + pub events: Vec, } /// Each function in the contract will be compiled as a separate noir program. diff --git a/tooling/nargo_cli/src/cli/compile_cmd.rs b/tooling/nargo_cli/src/cli/compile_cmd.rs index d7bcf475a40..7ac7fe58500 100644 --- a/tooling/nargo_cli/src/cli/compile_cmd.rs +++ b/tooling/nargo_cli/src/cli/compile_cmd.rs @@ -267,6 +267,7 @@ fn save_contract( name: contract.name, backend: String::from(BACKEND_IDENTIFIER), functions: preprocessed_functions, + events: contract.events, }; save_contract_to_file( diff --git a/tooling/nargo_cli/tests/execution_success/regression_2854/Nargo.toml b/tooling/nargo_cli/tests/execution_success/regression_2854/Nargo.toml new file mode 100644 index 00000000000..33bd007d898 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/regression_2854/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "regression_2854" +type = "bin" +authors = [""] +compiler_version = "0.1" + +[dependencies] diff --git a/tooling/nargo_cli/tests/execution_success/regression_2854/Prover.toml b/tooling/nargo_cli/tests/execution_success/regression_2854/Prover.toml new file mode 100644 index 00000000000..07890234a19 --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/regression_2854/Prover.toml @@ -0,0 +1 @@ +x = "3" diff --git a/tooling/nargo_cli/tests/execution_success/regression_2854/src/main.nr b/tooling/nargo_cli/tests/execution_success/regression_2854/src/main.nr new file mode 100644 index 00000000000..10ada5faeec --- /dev/null +++ b/tooling/nargo_cli/tests/execution_success/regression_2854/src/main.nr @@ -0,0 +1,3 @@ +fn main(x: Field) -> pub i127 { + x as i127 +} \ No newline at end of file diff --git a/tooling/noir_js/package.json b/tooling/noir_js/package.json index dd6e4c6bab5..bba952e39e3 100644 --- a/tooling/noir_js/package.json +++ b/tooling/noir_js/package.json @@ -18,10 +18,10 @@ ], "source": "src/index.ts", "main": "lib/index.cjs", - "module": "lib/index.js", + "module": "lib/index.mjs", "exports": { "require": "./lib/index.cjs", - "default": "./lib/index.js", + "default": "./lib/index.mjs", "types": "./lib/index.d.ts" }, "types": "lib/index.d.ts", @@ -33,7 +33,9 @@ "test:node:cjs": "mocha --timeout 25000 --exit --config ./.mocharc.cjs.json", "prettier": "prettier 'src/**/*.ts'", "prettier:fix": "prettier --write 'src/**/*.ts' 'test/**/*.ts'", - "lint": "NODE_NO_WARNINGS=1 eslint . --ext .ts --ignore-path ./.eslintignore --max-warnings 0" + "lint": "NODE_NO_WARNINGS=1 eslint . --ext .ts --ignore-path ./.eslintignore --max-warnings 0", + "clean": "rm -rf ./lib" + }, "devDependencies": { "@aztec/bb.js": "0.7.2", diff --git a/tooling/noirc_abi/src/lib.rs b/tooling/noirc_abi/src/lib.rs index d0c7e4e58c1..eb654e25f8c 100644 --- a/tooling/noirc_abi/src/lib.rs +++ b/tooling/noirc_abi/src/lib.rs @@ -12,7 +12,9 @@ use acvm::{ use errors::AbiError; use input_parser::InputValue; use iter_extended::{try_btree_map, try_vecmap, vecmap}; -use noirc_frontend::{hir::Context, Signedness, Type, TypeBinding, TypeVariableKind, Visibility}; +use noirc_frontend::{ + hir::Context, Signedness, StructType, Type, TypeBinding, TypeVariableKind, Visibility, +}; use serde::{Deserialize, Serialize}; // This is the ABI used to bridge the different TOML formats for the initial // witness, the partial witness generator and the interpreter. @@ -477,6 +479,33 @@ fn decode_string_value(field_elements: &[FieldElement]) -> String { final_string.to_owned() } +#[derive(Debug, Serialize, Deserialize)] +pub struct ContractEvent { + /// Event name + name: String, + /// The fully qualified path to the event definition + path: String, + + /// Fields of the event + #[serde( + serialize_with = "serialization::serialize_struct_fields", + deserialize_with = "serialization::deserialize_struct_fields" + )] + fields: Vec<(String, AbiType)>, +} + +impl ContractEvent { + pub fn from_struct_type(context: &Context, struct_type: &StructType) -> Self { + let fields = vecmap(struct_type.get_fields(&[]), |(name, typ)| { + (name, AbiType::from_type(context, &typ)) + }); + // For the ABI, we always want to resolve the struct paths from the root crate + let path = context.fully_qualified_struct_path(context.root_crate_id(), struct_type.id); + + Self { name: struct_type.name.0.contents.clone(), path, fields } + } +} + #[cfg(test)] mod test { use std::collections::BTreeMap; diff --git a/tooling/noirc_abi_wasm/package.json b/tooling/noirc_abi_wasm/package.json index 6da00a37d35..1d500d2464b 100644 --- a/tooling/noirc_abi_wasm/package.json +++ b/tooling/noirc_abi_wasm/package.json @@ -25,7 +25,7 @@ "build": "bash ./build.sh", "test": "env TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\" }' mocha", "test:browser": "web-test-runner", - "clean": "rm -rf ./nodejs ./web ./target ./result", + "clean": "chmod u+w web nodejs && rm -rf ./nodejs ./web ./target ./result", "lint": "NODE_NO_WARNINGS=1 eslint . --ext .ts --ignore-path ./.eslintignore --max-warnings 0" }, "devDependencies": {