From 0026b864aca3e2b36e354ae24a46e1db352c6439 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Tue, 7 May 2024 08:42:26 +0000 Subject: [PATCH 1/9] wip demonomorphizer in type generator --- .../noir-protocol-circuits/Nargo.toml | 1 + .../crates/test/Nargo.toml | 7 + .../crates/test/src/main.nr | 23 ++ yarn-project/foundation/src/abi/abi.ts | 19 +- yarn-project/foundation/src/abi/encoder.ts | 2 + .../noir-protocol-circuits-types/package.json | 1 + .../src/scripts/abi_type_with_generics.ts | 112 ++++++++ .../src/scripts/demonomorphizer.ts | 247 ++++++++++++++++++ .../src/scripts/generate_ts_from_abi.ts | 191 ++++++++++++++ yarn-project/yarn.lock | 8 + 10 files changed, 610 insertions(+), 1 deletion(-) create mode 100644 noir-projects/noir-protocol-circuits/crates/test/Nargo.toml create mode 100644 noir-projects/noir-protocol-circuits/crates/test/src/main.nr create mode 100644 yarn-project/noir-protocol-circuits-types/src/scripts/abi_type_with_generics.ts create mode 100644 yarn-project/noir-protocol-circuits-types/src/scripts/demonomorphizer.ts diff --git a/noir-projects/noir-protocol-circuits/Nargo.toml b/noir-projects/noir-protocol-circuits/Nargo.toml index 48cc2fc96f6..9f4b3219c12 100644 --- a/noir-projects/noir-protocol-circuits/Nargo.toml +++ b/noir-projects/noir-protocol-circuits/Nargo.toml @@ -28,4 +28,5 @@ members = [ "crates/rollup-base", "crates/rollup-base-simulated", "crates/rollup-root", + "crates/test", ] diff --git a/noir-projects/noir-protocol-circuits/crates/test/Nargo.toml b/noir-projects/noir-protocol-circuits/crates/test/Nargo.toml new file mode 100644 index 00000000000..1565c2ee78c --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/test/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "test" +type = "bin" +authors = [""] +compiler_version = ">=0.18.0" + +[dependencies] diff --git a/noir-projects/noir-protocol-circuits/crates/test/src/main.nr b/noir-projects/noir-protocol-circuits/crates/test/src/main.nr new file mode 100644 index 00000000000..87a19715bc1 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/test/src/main.nr @@ -0,0 +1,23 @@ +struct Array { + inner: [u32; N], +} + +struct Foo { + bar: Array, +} + +struct Bar { + baz: T, +} + +use dep::std::option::Option; + +fn main( + a: Bar>, + b: Foo<2>, + c: Foo<3>, + d: Bar>, + e: Bar, + f: Option>, + g: Option +) {} diff --git a/yarn-project/foundation/src/abi/abi.ts b/yarn-project/foundation/src/abi/abi.ts index 3dbe2dc7036..92bc10a482f 100644 --- a/yarn-project/foundation/src/abi/abi.ts +++ b/yarn-project/foundation/src/abi/abi.ts @@ -86,7 +86,14 @@ export interface BasicType { /** * A variable type. */ -export type AbiType = BasicType<'field'> | BasicType<'boolean'> | IntegerType | ArrayType | StringType | StructType; +export type AbiType = + | BasicType<'field'> + | BasicType<'boolean'> + | IntegerType + | ArrayType + | StringType + | StructType + | TupleType; /** * An integer type. @@ -140,6 +147,16 @@ export interface StructType extends BasicType<'struct'> { path: string; } +/** + * A tuple type. + */ +export interface TupleType extends BasicType<'tuple'> { + /** + * The fields of the tuple. + */ + fields: AbiType[]; +} + /** * Aztec.nr function types. */ diff --git a/yarn-project/foundation/src/abi/encoder.ts b/yarn-project/foundation/src/abi/encoder.ts index 119554935af..ca15ad524d1 100644 --- a/yarn-project/foundation/src/abi/encoder.ts +++ b/yarn-project/foundation/src/abi/encoder.ts @@ -23,6 +23,8 @@ class ArgumentEncoder { return abiType.length * ArgumentEncoder.typeSize(abiType.type); case 'struct': return abiType.fields.reduce((acc, field) => acc + ArgumentEncoder.typeSize(field.type), 0); + case 'tuple': + return abiType.fields.reduce((acc, field) => acc + ArgumentEncoder.typeSize(field), 0); default: { const exhaustiveCheck: never = abiType; throw new Error(`Unhandled abi type: ${exhaustiveCheck}`); diff --git a/yarn-project/noir-protocol-circuits-types/package.json b/yarn-project/noir-protocol-circuits-types/package.json index c8bcbff9171..50b836ba0e8 100644 --- a/yarn-project/noir-protocol-circuits-types/package.json +++ b/yarn-project/noir-protocol-circuits-types/package.json @@ -61,6 +61,7 @@ "@jest/globals": "^29.5.0", "@types/jest": "^29.5.0", "@types/node": "^18.7.23", + "change-case": "^5.4.4", "jest": "^29.5.0", "levelup": "^5.1.1", "memdown": "^6.1.1", diff --git a/yarn-project/noir-protocol-circuits-types/src/scripts/abi_type_with_generics.ts b/yarn-project/noir-protocol-circuits-types/src/scripts/abi_type_with_generics.ts new file mode 100644 index 00000000000..0e7cc1d3d66 --- /dev/null +++ b/yarn-project/noir-protocol-circuits-types/src/scripts/abi_type_with_generics.ts @@ -0,0 +1,112 @@ +import { type AbiType } from '@aztec/foundation/abi'; + +export class BindingId { + constructor(public id: number, public isNumeric: boolean) {} +} + +export type StructType = { path: string; fields: { name: string; type: AbiTypeWithGenerics }[]; generics: BindingId[] }; + +export type StringType = { + kind: 'string'; + length: number | BindingId; +}; + +export type Constant = { + kind: 'constant'; + value: number; +}; + +export type ArrayType = { + kind: 'array'; + length: number | BindingId; + type: AbiTypeWithGenerics; +}; + +export type Tuple = { + kind: 'tuple'; + fields: AbiTypeWithGenerics[]; +}; + +export type Struct = { + kind: 'struct'; + structType: StructType; + args: AbiTypeWithGenerics[]; +}; + +export type AbiTypeWithGenerics = + | { kind: 'field' } + | { kind: 'boolean' } + | { kind: 'integer'; sign: string; width: number } + | { kind: 'binding'; id: BindingId } + | { kind: 'constant'; value: number } + | StringType + | ArrayType + | Tuple + | Struct; + +export function mapAbiTypeToAbiTypeWithGenerics(abiType: AbiType): AbiTypeWithGenerics { + switch (abiType.kind) { + case 'field': + case 'boolean': + case 'string': + case 'integer': + return abiType; + case 'array': + return { + kind: 'array', + length: abiType.length, + type: mapAbiTypeToAbiTypeWithGenerics(abiType.type), + }; + case 'tuple': + return { + kind: 'tuple', + fields: abiType.fields.map(field => mapAbiTypeToAbiTypeWithGenerics(field)), + }; + case 'struct': { + const structType = { + path: abiType.path, + fields: abiType.fields.map(field => ({ + name: field.name, + type: mapAbiTypeToAbiTypeWithGenerics(field.type), + })), + generics: [], + }; + return { + kind: 'struct', + structType, + args: [], + }; + } + } +} + +export function findStructsInType(abiType: AbiTypeWithGenerics): Struct[] { + switch (abiType.kind) { + case 'field': + case 'boolean': + case 'string': + case 'integer': + return []; + case 'array': + return findStructsInType(abiType.type); + case 'tuple': + return abiType.fields.flatMap(findStructsInType); + case 'struct': + return [abiType]; + default: { + return []; + } + } +} + +export function findAllStructsInType(abiType: AbiTypeWithGenerics): Struct[] { + let allStructs: Struct[] = []; + let lastStructs = findStructsInType(abiType); + while (lastStructs.length > 0) { + allStructs = allStructs.concat(lastStructs); + lastStructs = lastStructs.flatMap(struct => + struct.structType.fields.flatMap(field => findStructsInType(field.type)), + ); + } + return allStructs; +} diff --git a/yarn-project/noir-protocol-circuits-types/src/scripts/demonomorphizer.ts b/yarn-project/noir-protocol-circuits-types/src/scripts/demonomorphizer.ts new file mode 100644 index 00000000000..d05cc46773d --- /dev/null +++ b/yarn-project/noir-protocol-circuits-types/src/scripts/demonomorphizer.ts @@ -0,0 +1,247 @@ +import { + type AbiTypeWithGenerics, + type ArrayType, + BindingId, + type Constant, + type StringType, + type Struct, + type StructType, + type Tuple, + findAllStructsInType, + findStructsInType, +} from './abi_type_with_generics.js'; + +export class Demonomorphizer { + private variantsMap: Map; + private visitedStructs: Map; + private lastBindingId = 0; + + public static demonomorphize( + abiTypes: AbiTypeWithGenerics[], // Mutates passed in types + ) { + new Demonomorphizer(abiTypes); + } + + private constructor(private types: AbiTypeWithGenerics[]) { + this.variantsMap = new Map(); + this.fillVariantsMap(); + + this.visitedStructs = new Map(); + this.demonomorphizeStructs(); + } + + private fillVariantsMap() { + const allStructs = this.types.flatMap(findAllStructsInType); + for (const struct of allStructs) { + const id = Demonomorphizer.buildIdForStruct(struct); + const variants = this.variantsMap.get(id) ?? []; + variants.push(struct); + this.variantsMap.set(id, variants); + } + } + + private demonomorphizeStructs() { + for (const type of this.types) { + const topLevelStructs = findStructsInType(type); + for (const struct of topLevelStructs) { + this.demonomorphizeStruct(struct); + } + } + } + + private demonomorphizeStruct(struct: Struct) { + const id = Demonomorphizer.buildIdForStruct(struct); + if (this.visitedStructs.has(id)) { + return; + } + const dependencies = struct.structType.fields.flatMap(field => findStructsInType(field.type)); + for (const dependency of dependencies) { + this.demonomorphizeStruct(dependency); + } + if (this.visitedStructs.has(id)) { + throw new Error('Circular dependency detected'); + } + + const variants = this.variantsMap.get(id)!; + const mappedStructType = struct.structType; + + for (let i = 0; i < struct.structType.fields.length; i++) { + const variantTypes = variants.map(variant => variant.structType.fields[i].type); + const mappedType = this.unifyTypes(variantTypes, mappedStructType.generics, variants); + mappedStructType.fields[i].type = mappedType; + } + + // Mutate variants setting the new struct type + variants.forEach(variant => (variant.structType = mappedStructType)); + + this.visitedStructs.set(id, mappedStructType); + } + + private unifyTypes( + types: AbiTypeWithGenerics[], + generics: BindingId[], // Mutates generics adding new bindings + variants: Struct[], // mutates variants adding different args to the variants + ): AbiTypeWithGenerics { + const kinds = new Set(types.map(type => type.kind)); + if (kinds.size > 1) { + return this.buildBindingAndPushToVariants(types, generics, variants); + } + switch (types[0].kind) { + case 'field': + case 'boolean': + case 'binding': + return structuredClone(types[0]); + case 'integer': { + if (allDeepEqual(types)) { + return structuredClone(types[0]); + } else { + return this.buildBindingAndPushToVariants(types, generics, variants); + } + } + case 'string': { + const strings = types as StringType[]; + const newString = structuredClone(strings[0]); + if (strings.every(string => string.length === newString.length)) { + return newString; + } else { + const newStringType: StringType = newString; + newStringType.length = this.buildNumericBindingAndPushToVariants( + strings.map(string => { + if (typeof string.length !== 'number') { + throw new Error('Trying to unify strings with bindings'); + } + return string.length; + }), + generics, + variants, + ); + return newStringType; + } + } + case 'array': { + const arrays = types as ArrayType[]; + const newArrayType: ArrayType = structuredClone(arrays[0]); + if ( + !arrays.every(array => { + return array.length === newArrayType.length; + }) + ) { + newArrayType.length = this.buildNumericBindingAndPushToVariants( + arrays.map(array => { + if (typeof array.length !== 'number') { + throw new Error('Trying to unify arrays with bindings'); + } + return array.length; + }), + generics, + variants, + ); + } + + newArrayType.type = this.unifyTypes( + arrays.map(array => array.type), + generics, + variants, + ); + return newArrayType; + } + case 'tuple': { + const tuples = types as Tuple[]; + const newTupleType: Tuple = structuredClone(tuples[0]); + for (let i = 0; i < newTupleType.fields.length; i++) { + newTupleType.fields[i] = this.unifyTypes( + tuples.map(tuple => tuple.fields[i]), + generics, + variants, + ); + } + return newTupleType; + } + case 'struct': { + const structs = types as Struct[]; + const ids = new Set(structs.map(Demonomorphizer.buildIdForStruct)); + if (ids.size > 1) { + return this.buildBindingAndPushToVariants(types, generics, variants); + } else { + const newStruct = structuredClone(structs[0]); + + if (!structs.every(struct => struct.args.length === structs[0].args.length)) { + throw new Error('Same struct with different number of args encountered'); + } + for (let i = 0; i < newStruct.args.length; i++) { + const argTypes = structs.map(struct => struct.args[i]); + newStruct.args[i] = this.unifyTypes(argTypes, generics, variants); + } + return newStruct; + } + } + + case 'constant': { + const constants = types as Constant[]; + if (constants.every(constant => constant.value === constants[0].value)) { + return structuredClone(constants[0]); + } else { + return this.buildBindingAndPushToVariants(types, generics, variants, true); + } + } + + default: { + const exhaustiveCheck: never = types[0]; + throw new Error(`Unhandled abi type: ${exhaustiveCheck}`); + } + } + } + + public static buildIdForStruct(struct: Struct): string { + const name = struct.structType.path.split('::').pop()!; + const fields = struct.structType.fields.map(field => field.name).join(','); + return `${name}(${fields})`; + } + + private buildBindingAndPushToVariants( + concreteTypes: AbiTypeWithGenerics[], + generics: BindingId[], + variants: Struct[], + isNumeric = false, + ): AbiTypeWithGenerics { + const bindingId = new BindingId(this.lastBindingId++, isNumeric); + + for (let i = 0; i < variants.length; i++) { + const variant = variants[i]; + const concreteType = concreteTypes[i]; + variant.args.push(concreteType); + } + + generics.push(bindingId); + return { kind: 'binding', id: bindingId }; + } + + private buildNumericBindingAndPushToVariants( + concreteNumbers: number[], + generics: BindingId[], + variants: Struct[], + ): BindingId { + const bindingId = new BindingId(this.lastBindingId++, true); + + for (let i = 0; i < variants.length; i++) { + const variant = variants[i]; + variant.args.push({ kind: 'constant', value: concreteNumbers[i] }); + } + + generics.push(bindingId); + return bindingId; + } +} + +function allDeepEqual(arr: T[]): boolean { + if (arr.length === 0) { + return true; + } + const first = JSON.stringify(arr[0]); + for (let i = 0; i < arr.length; i++) { + if (JSON.stringify(arr[i]) !== first) { + return false; + } + } + return true; +} diff --git a/yarn-project/noir-protocol-circuits-types/src/scripts/generate_ts_from_abi.ts b/yarn-project/noir-protocol-circuits-types/src/scripts/generate_ts_from_abi.ts index 8b8f29d890f..399e665b566 100644 --- a/yarn-project/noir-protocol-circuits-types/src/scripts/generate_ts_from_abi.ts +++ b/yarn-project/noir-protocol-circuits-types/src/scripts/generate_ts_from_abi.ts @@ -2,8 +2,18 @@ import { type AbiType } from '@aztec/foundation/abi'; import { createConsoleLogger } from '@aztec/foundation/log'; import { type NoirCompiledCircuit, type NoirFunctionAbi } from '@aztec/types/noir'; +import { pascalCase } from 'change-case'; import fs from 'fs/promises'; +import { + type AbiTypeWithGenerics, + type BindingId, + type StructType, + findAllStructsInType, + mapAbiTypeToAbiTypeWithGenerics, +} from './abi_type_with_generics.js'; +import { Demonomorphizer } from './demonomorphizer.js'; + const log = createConsoleLogger('aztec:noir-contracts'); /** @@ -197,6 +207,177 @@ function generateTsInterface(abiObj: NoirFunctionAbi): string { ); } +function replaceNumericBinding(id: number | BindingId, genericsNameMap: Map): string { + if (typeof id === 'number') { + return id.toString(); + } else { + return genericsNameMap.get(id.id) ?? 'unknown'; + } +} + +class TypingsGenerator { + private primitiveTypesUsed = new Map(); + private allTypes: AbiTypeWithGenerics[] = []; + private monomorphizedAbis: { + circuitName: string; + params: { name: string; type: AbiTypeWithGenerics }[]; + returnType?: AbiTypeWithGenerics; + }[] = []; + + constructor(circuits: { abi: NoirFunctionAbi; circuitName: string }[]) { + for (const { abi, circuitName } of circuits) { + const params = abi.parameters.map(param => { + const type = mapAbiTypeToAbiTypeWithGenerics(param.type); + this.allTypes.push(type); + return { name: param.name, type }; + }); + if (abi.return_type) { + const returnType = mapAbiTypeToAbiTypeWithGenerics(abi.return_type.abi_type); + this.allTypes.push(returnType); + this.monomorphizedAbis.push({ circuitName, params, returnType }); + } else { + this.monomorphizedAbis.push({ circuitName, params }); + } + } + Demonomorphizer.demonomorphize(this.allTypes); + } + + public codegen(): string { + this.primitiveTypesUsed = new Map(); + const structsCode = this.codegenAllStructs(); + const interfacesCode = this.codegenAllInterfaces(); + const primitivesCode = this.codegenAllPrimitives(); + + return ` + /* Autogenerated file, do not edit! */ + /* eslint-disable */ + ${primitivesCode} + ${structsCode} + ${interfacesCode}`; + } + + private codegenAllStructs(): string { + const allStructs = this.allTypes.flatMap(findAllStructsInType); + const structTypesToExport = new Map(); + for (const struct of allStructs) { + const id = Demonomorphizer.buildIdForStruct(struct); + if (structTypesToExport.has(id)) { + continue; + } + structTypesToExport.set(id, struct.structType); + } + + let resultCode = ''; + + for (const structType of structTypesToExport.values()) { + resultCode += this.codegenStructType(structType); + } + + return resultCode; + } + + private codegenStructType(structType: StructType): string { + const genericsNameMap = new Map(); + structType.generics.forEach((generic, index) => { + genericsNameMap.set(generic.id, String.fromCharCode('A'.charCodeAt(0) + index)); + }); + const name = structType.path.split('::').pop(); + const generics = structType.generics.length + ? `<${structType.generics + .map(generic => `${genericsNameMap.get(generic.id)}${generic.isNumeric ? ' extends number' : ''}`) + .join(', ')}>` + : ''; + let resultCode = `export interface ${name}${generics} {\n`; + + for (const field of structType.fields) { + resultCode += ` ${field.name}: ${this.codegenType(field.type, genericsNameMap)};\n`; + } + + resultCode += '}\n\n'; + + return resultCode; + } + + private codegenType(type: AbiTypeWithGenerics, genericsNameMap: Map): string { + switch (type.kind) { + case 'field': + this.addIfUnique({ aliasName: 'Field', tsType: 'string' }); + return 'Field'; + case 'boolean': + return 'boolean'; + case 'integer': { + let tsIntType = ''; + if (type.sign === 'signed') { + tsIntType = `i${type.width}`; + } else { + tsIntType = `u${type.width}`; + } + this.addIfUnique({ aliasName: tsIntType, tsType: 'string' }); + return tsIntType; + } + case 'binding': + return genericsNameMap.get(type.id.id) ?? 'unknown'; + case 'constant': + return type.value.toString(); + case 'string': + return `string`; + case 'array': + return `FixedLengthArray<${this.codegenType(type.type, genericsNameMap)}, ${replaceNumericBinding( + type.length, + genericsNameMap, + )}>`; + case 'tuple': + throw new Error('Unimplemented'); + case 'struct': { + const name = type.structType.path.split('::').pop()!; + if (type.args.length) { + const args = type.args.map(arg => this.codegenType(arg, genericsNameMap)).join(', '); + return `${name}<${args}>`; + } else { + return name; + } + } + } + } + + /** + * Typescript does not allow us to check for equality of non-primitive types + * easily, so we create a addIfUnique function that will only add an item + * to the map if it is not already there by using JSON.stringify. + * @param item - The item to add to the map. + */ + private addIfUnique(item: PrimitiveTypesUsed) { + const key = JSON.stringify(item); + if (!this.primitiveTypesUsed.has(key)) { + this.primitiveTypesUsed.set(key, item); + } + } + + private codegenAllInterfaces(): string { + let resultCode = ''; + for (const { circuitName, params, returnType } of this.monomorphizedAbis) { + resultCode += this.codegenStructType({ + path: `${circuitName}InputType`, + fields: params, + generics: [], + }); + if (returnType) { + resultCode += `export type ${circuitName}ReturnType = ${this.codegenType(returnType, new Map())};\n`; + } + } + return resultCode; + } + + private codegenAllPrimitives(): string { + let primitiveTypeAliases = + 'export type FixedLengthArray = L extends 0 ? never[]: T[] & { length: L }\n'; + for (const [, value] of noirPrimitiveTypesToTsTypes) { + primitiveTypeAliases += `export type ${value.aliasName} = ${value.tsType};\n`; + } + return primitiveTypeAliases; + } +} + const circuits = [ 'parity_base', 'parity_root', @@ -211,6 +392,7 @@ const circuits = [ 'rollup_base', 'rollup_merge', 'rollup_root', + 'test', ]; const main = async () => { @@ -220,14 +402,23 @@ const main = async () => { await fs.mkdir('./src/types', { recursive: true }); } + const allAbis = []; + for (const circuit of circuits) { const rawData = await fs.readFile(`./src/target/${circuit}.json`, 'utf-8'); const abiObj: NoirCompiledCircuit = JSON.parse(rawData); const generatedInterface = generateTsInterface(abiObj.abi); + allAbis.push({ + abi: abiObj.abi, + circuitName: pascalCase(circuit), + }); const outputFile = `./src/types/${circuit}_types.ts`; await fs.writeFile(outputFile, generatedInterface); } + + const typing = new TypingsGenerator(allAbis).codegen(); + await fs.writeFile(`./src/types/types.ts`, typing); }; try { diff --git a/yarn-project/yarn.lock b/yarn-project/yarn.lock index f2539b2eb46..65a9882c947 100644 --- a/yarn-project/yarn.lock +++ b/yarn-project/yarn.lock @@ -592,6 +592,7 @@ __metadata: "@noir-lang/types": "portal:../../noir/packages/types" "@types/jest": ^29.5.0 "@types/node": ^18.7.23 + change-case: ^5.4.4 jest: ^29.5.0 levelup: ^5.1.1 memdown: ^6.1.1 @@ -5255,6 +5256,13 @@ __metadata: languageName: node linkType: hard +"change-case@npm:^5.4.4": + version: 5.4.4 + resolution: "change-case@npm:5.4.4" + checksum: a22a25a763719658424ffbcd41e931d2d19cc22399cc765dca447fbe1eaf13e179d5e8ab1677af75f2e814dbddf74e42ffdecb526cd5bc906cc859f62aa154b2 + languageName: node + linkType: hard + "char-regex@npm:^1.0.2": version: 1.0.2 resolution: "char-regex@npm:1.0.2" From 9cafcb4ebf2af4d1751a4c5924321946cfc20aea Mon Sep 17 00:00:00 2001 From: sirasistant Date: Tue, 7 May 2024 09:26:12 +0000 Subject: [PATCH 2/9] use new typing system --- .../noir-protocol-circuits-types/src/index.ts | 28 +-- .../src/scripts/demonomorphizer.ts | 12 +- .../src/scripts/generate_ts_from_abi.ts | 191 ++++-------------- 3 files changed, 54 insertions(+), 177 deletions(-) diff --git a/yarn-project/noir-protocol-circuits-types/src/index.ts b/yarn-project/noir-protocol-circuits-types/src/index.ts index 6e48dddc7a3..d3f69ae3246 100644 --- a/yarn-project/noir-protocol-circuits-types/src/index.ts +++ b/yarn-project/noir-protocol-circuits-types/src/index.ts @@ -71,26 +71,26 @@ import { mapRootRollupInputsToNoir, mapRootRollupPublicInputsFromNoir, } from './type_conversion.js'; -import { type ReturnType as BaseParityReturnType } from './types/parity_base_types.js'; -import { type ReturnType as RootParityReturnType } from './types/parity_root_types.js'; +import { type ParityBaseReturnType as BaseParityReturnType } from './types/parity_base_types.js'; +import { type ParityRootReturnType as RootParityReturnType } from './types/parity_root_types.js'; import { - type InputType as InitInputType, - type ReturnType as InitReturnType, + type PrivateKernelInitInputType as InitInputType, + type PrivateKernelInitReturnType as InitReturnType, } from './types/private_kernel_init_types.js'; import { - type InputType as InnerInputType, - type ReturnType as InnerReturnType, + type PrivateKernelInnerInputType as InnerInputType, + type PrivateKernelInnerReturnType as InnerReturnType, } from './types/private_kernel_inner_types.js'; -import { type InputType as TailToPublicInputType } from './types/private_kernel_tail_to_public_types.js'; +import { type PrivateKernelTailToPublicInputType as TailToPublicInputType } from './types/private_kernel_tail_to_public_types.js'; import { - type InputType as TailInputType, - type ReturnType as TailReturnType, + type PrivateKernelTailInputType as TailInputType, + type PrivateKernelTailReturnType as TailReturnType, } from './types/private_kernel_tail_types.js'; -import { type ReturnType as PublicPublicPreviousReturnType } from './types/public_kernel_app_logic_types.js'; -import { type ReturnType as PublicSetupReturnType } from './types/public_kernel_setup_types.js'; -import { type ReturnType as BaseRollupReturnType } from './types/rollup_base_types.js'; -import { type ReturnType as MergeRollupReturnType } from './types/rollup_merge_types.js'; -import { type ReturnType as RootRollupReturnType } from './types/rollup_root_types.js'; +import { type PublicKernelAppLogicReturnType as PublicPublicPreviousReturnType } from './types/public_kernel_app_logic_types.js'; +import { type PublicKernelSetupReturnType as PublicSetupReturnType } from './types/public_kernel_setup_types.js'; +import { type RollupBaseReturnType as BaseRollupReturnType } from './types/rollup_base_types.js'; +import { type RollupMergeReturnType as MergeRollupReturnType } from './types/rollup_merge_types.js'; +import { type RollupRootReturnType as RootRollupReturnType } from './types/rollup_root_types.js'; // TODO(Tom): This should be exported from noirc_abi /** diff --git a/yarn-project/noir-protocol-circuits-types/src/scripts/demonomorphizer.ts b/yarn-project/noir-protocol-circuits-types/src/scripts/demonomorphizer.ts index d05cc46773d..a7045c14d99 100644 --- a/yarn-project/noir-protocol-circuits-types/src/scripts/demonomorphizer.ts +++ b/yarn-project/noir-protocol-circuits-types/src/scripts/demonomorphizer.ts @@ -33,7 +33,7 @@ export class Demonomorphizer { private fillVariantsMap() { const allStructs = this.types.flatMap(findAllStructsInType); for (const struct of allStructs) { - const id = Demonomorphizer.buildIdForStruct(struct); + const id = Demonomorphizer.buildIdForStruct(struct.structType); const variants = this.variantsMap.get(id) ?? []; variants.push(struct); this.variantsMap.set(id, variants); @@ -50,7 +50,7 @@ export class Demonomorphizer { } private demonomorphizeStruct(struct: Struct) { - const id = Demonomorphizer.buildIdForStruct(struct); + const id = Demonomorphizer.buildIdForStruct(struct.structType); if (this.visitedStructs.has(id)) { return; } @@ -159,7 +159,7 @@ export class Demonomorphizer { } case 'struct': { const structs = types as Struct[]; - const ids = new Set(structs.map(Demonomorphizer.buildIdForStruct)); + const ids = new Set(structs.map(struct => Demonomorphizer.buildIdForStruct(struct.structType))); if (ids.size > 1) { return this.buildBindingAndPushToVariants(types, generics, variants); } else { @@ -192,9 +192,9 @@ export class Demonomorphizer { } } - public static buildIdForStruct(struct: Struct): string { - const name = struct.structType.path.split('::').pop()!; - const fields = struct.structType.fields.map(field => field.name).join(','); + public static buildIdForStruct(struct: StructType): string { + const name = struct.path.split('::').pop()!; + const fields = struct.fields.map(field => field.name).join(','); return `${name}(${fields})`; } diff --git a/yarn-project/noir-protocol-circuits-types/src/scripts/generate_ts_from_abi.ts b/yarn-project/noir-protocol-circuits-types/src/scripts/generate_ts_from_abi.ts index 399e665b566..323529366f9 100644 --- a/yarn-project/noir-protocol-circuits-types/src/scripts/generate_ts_from_abi.ts +++ b/yarn-project/noir-protocol-circuits-types/src/scripts/generate_ts_from_abi.ts @@ -1,4 +1,3 @@ -import { type AbiType } from '@aztec/foundation/abi'; import { createConsoleLogger } from '@aztec/foundation/log'; import { type NoirCompiledCircuit, type NoirFunctionAbi } from '@aztec/types/noir'; @@ -40,52 +39,6 @@ type PrimitiveTypesUsed = { tsType: string; }; -const noirPrimitiveTypesToTsTypes = new Map(); - -/** - * Typescript does not allow us to check for equality of non-primitive types - * easily, so we create a addIfUnique function that will only add an item - * to the map if it is not already there by using JSON.stringify. - * @param item - The item to add to the map. - */ -function addIfUnique(item: PrimitiveTypesUsed) { - const key = JSON.stringify(item); - if (!noirPrimitiveTypesToTsTypes.has(key)) { - noirPrimitiveTypesToTsTypes.set(key, item); - } -} - -/** - * Converts an ABI type to a TypeScript type. - * @param type - The ABI type to convert. - * @returns The typescript code to define the type. - */ -function abiTypeToTs(type: AbiType): string { - switch (type.kind) { - case 'integer': { - let tsIntType = ''; - if (type.sign === 'signed') { - tsIntType = `i${type.width}`; - } else { - tsIntType = `u${type.width}`; - } - addIfUnique({ aliasName: tsIntType, tsType: 'string' }); - return tsIntType; - } - case 'boolean': - return `boolean`; - case 'array': - return `FixedLengthArray<${abiTypeToTs(type.type)}, ${type.length}>`; - case 'struct': - return getLastComponentOfPath(type.path); - case 'field': - addIfUnique({ aliasName: 'Field', tsType: 'string' }); - return 'Field'; - default: - throw new Error(`Unknown ABI type ${type}`); - } -} - /** * Returns the last component of a path, e.g. "foo::bar::baz" -\> "baz" * Note: that if we have a path such as "Baz", we will return "Baz". @@ -111,102 +64,6 @@ function getLastComponentOfPath(str: string): string { return lastPart; } -/** - * Generates TypeScript interfaces for the structs used in the ABI. - * @param type - The ABI type to generate the interface for. - * @param output - The set of structs that we have already generated bindings for. - * @returns The TypeScript code to define the struct. - */ -function generateStructInterfaces(type: AbiType, output: Set): string { - let result = ''; - - // Edge case to handle the array of structs case. - if ( - type.kind === 'array' && - ((type.type.kind === 'struct' && !output.has(getLastComponentOfPath(type.type.path))) || type.type.kind === 'array') - ) { - result += generateStructInterfaces(type.type, output); - } - - if (type.kind !== 'struct') { - return result; - } - - // List of structs encountered while viewing this type that we need to generate - // bindings for. - const typesEncountered = new Set(); - - // Codegen the struct and then its fields, so that the structs fields - // are defined before the struct itself. - let codeGeneratedStruct = ''; - let codeGeneratedStructFields = ''; - - const structName = getLastComponentOfPath(type.path); - if (!output.has(structName)) { - codeGeneratedStruct += `export interface ${structName} {\n`; - for (const field of type.fields) { - codeGeneratedStruct += ` ${field.name}: ${abiTypeToTs(field.type)};\n`; - typesEncountered.add(field.type); - } - codeGeneratedStruct += `}\n\n`; - output.add(structName); - - // Generate code for the encountered structs in the field above - for (const type of typesEncountered) { - codeGeneratedStructFields += generateStructInterfaces(type, output); - } - } - - return codeGeneratedStructFields + '\n' + codeGeneratedStruct; -} - -/** - * Generates a TypeScript interface for the ABI. - * @param abiObj - The ABI to generate the interface for. - * @returns The TypeScript code to define the interface. - */ -function generateTsInterface(abiObj: NoirFunctionAbi): string { - let result = ``; - const outputStructs = new Set(); - - // Define structs for composite types - for (const param of abiObj.parameters) { - result += generateStructInterfaces(param.type, outputStructs); - } - - // Generating Return type, if it exists - // - if (abiObj.return_type != null) { - result += generateStructInterfaces(abiObj.return_type.abi_type, outputStructs); - result += `export type ReturnType = ${abiTypeToTs(abiObj.return_type.abi_type)};\n`; - } - - // Generating Input type - result += '\nexport interface InputType {\n'; - for (const param of abiObj.parameters) { - result += ` ${param.name}: ${abiTypeToTs(param.type)};\n`; - } - result += '}'; - - // Add the primitive Noir types that do not have a 1-1 mapping to TypeScript. - let primitiveTypeAliases = ''; - for (const [, value] of noirPrimitiveTypesToTsTypes) { - primitiveTypeAliases += `\nexport type ${value.aliasName} = ${value.tsType};`; - } - - const fixedLengthArray = - '\nexport type FixedLengthArray = L extends 0 ? never[]: T[] & { length: L }'; - - return ( - `/* Autogenerated file, do not edit! */\n\n/* eslint-disable */\n` + - fixedLengthArray + - '\n' + - primitiveTypeAliases + - '\n' + - result - ); -} - function replaceNumericBinding(id: number | BindingId, genericsNameMap: Map): string { if (typeof id === 'number') { return id.toString(); @@ -223,6 +80,7 @@ class TypingsGenerator { params: { name: string; type: AbiTypeWithGenerics }[]; returnType?: AbiTypeWithGenerics; }[] = []; + private structIdToTsName = new Map(); constructor(circuits: { abi: NoirFunctionAbi; circuitName: string }[]) { for (const { abi, circuitName } of circuits) { @@ -260,13 +118,30 @@ class TypingsGenerator { const allStructs = this.allTypes.flatMap(findAllStructsInType); const structTypesToExport = new Map(); for (const struct of allStructs) { - const id = Demonomorphizer.buildIdForStruct(struct); + const id = Demonomorphizer.buildIdForStruct(struct.structType); if (structTypesToExport.has(id)) { continue; } structTypesToExport.set(id, struct.structType); } + const idsPerName = new Map(); + for (const [id, structType] of structTypesToExport.entries()) { + const name = getLastComponentOfPath(structType.path); + const ids = idsPerName.get(name) ?? []; + ids.push(id); + idsPerName.set(name, ids); + } + + this.structIdToTsName = new Map(); + for (const [name, ids] of idsPerName.entries()) { + if (ids.length !== 1) { + ids.forEach((id, index) => { + this.structIdToTsName.set(id, `${name}${index + 1}`); + }); + } + } + let resultCode = ''; for (const structType of structTypesToExport.values()) { @@ -276,12 +151,18 @@ class TypingsGenerator { return resultCode; } + private getStructName(structType: StructType): string { + return ( + this.structIdToTsName.get(Demonomorphizer.buildIdForStruct(structType)) || getLastComponentOfPath(structType.path) + ); + } + private codegenStructType(structType: StructType): string { const genericsNameMap = new Map(); structType.generics.forEach((generic, index) => { genericsNameMap.set(generic.id, String.fromCharCode('A'.charCodeAt(0) + index)); }); - const name = structType.path.split('::').pop(); + const name = this.getStructName(structType); const generics = structType.generics.length ? `<${structType.generics .map(generic => `${genericsNameMap.get(generic.id)}${generic.isNumeric ? ' extends number' : ''}`) @@ -329,7 +210,7 @@ class TypingsGenerator { case 'tuple': throw new Error('Unimplemented'); case 'struct': { - const name = type.structType.path.split('::').pop()!; + const name = this.getStructName(type.structType); if (type.args.length) { const args = type.args.map(arg => this.codegenType(arg, genericsNameMap)).join(', '); return `${name}<${args}>`; @@ -371,7 +252,7 @@ class TypingsGenerator { private codegenAllPrimitives(): string { let primitiveTypeAliases = 'export type FixedLengthArray = L extends 0 ? never[]: T[] & { length: L }\n'; - for (const [, value] of noirPrimitiveTypesToTsTypes) { + for (const [, value] of this.primitiveTypesUsed) { primitiveTypeAliases += `export type ${value.aliasName} = ${value.tsType};\n`; } return primitiveTypeAliases; @@ -402,23 +283,19 @@ const main = async () => { await fs.mkdir('./src/types', { recursive: true }); } - const allAbis = []; - for (const circuit of circuits) { const rawData = await fs.readFile(`./src/target/${circuit}.json`, 'utf-8'); const abiObj: NoirCompiledCircuit = JSON.parse(rawData); - const generatedInterface = generateTsInterface(abiObj.abi); - allAbis.push({ - abi: abiObj.abi, - circuitName: pascalCase(circuit), - }); + const generatedInterface = new TypingsGenerator([ + { + abi: abiObj.abi, + circuitName: pascalCase(circuit), + }, + ]).codegen(); const outputFile = `./src/types/${circuit}_types.ts`; await fs.writeFile(outputFile, generatedInterface); } - - const typing = new TypingsGenerator(allAbis).codegen(); - await fs.writeFile(`./src/types/types.ts`, typing); }; try { From 18010388fe282608c1b84443af5a68a977e567a8 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Tue, 7 May 2024 09:31:24 +0000 Subject: [PATCH 3/9] unify types in one file --- .../noir-protocol-circuits/Nargo.toml | 1 - .../crates/test/Nargo.toml | 7 - .../crates/test/src/main.nr | 23 ---- .../noir-protocol-circuits-types/src/index.ts | 22 ++-- .../src/scripts/generate_ts_from_abi.ts | 17 ++- .../src/type_conversion.ts | 124 ++++++++---------- 6 files changed, 71 insertions(+), 123 deletions(-) delete mode 100644 noir-projects/noir-protocol-circuits/crates/test/Nargo.toml delete mode 100644 noir-projects/noir-protocol-circuits/crates/test/src/main.nr diff --git a/noir-projects/noir-protocol-circuits/Nargo.toml b/noir-projects/noir-protocol-circuits/Nargo.toml index 9f4b3219c12..48cc2fc96f6 100644 --- a/noir-projects/noir-protocol-circuits/Nargo.toml +++ b/noir-projects/noir-protocol-circuits/Nargo.toml @@ -28,5 +28,4 @@ members = [ "crates/rollup-base", "crates/rollup-base-simulated", "crates/rollup-root", - "crates/test", ] diff --git a/noir-projects/noir-protocol-circuits/crates/test/Nargo.toml b/noir-projects/noir-protocol-circuits/crates/test/Nargo.toml deleted file mode 100644 index 1565c2ee78c..00000000000 --- a/noir-projects/noir-protocol-circuits/crates/test/Nargo.toml +++ /dev/null @@ -1,7 +0,0 @@ -[package] -name = "test" -type = "bin" -authors = [""] -compiler_version = ">=0.18.0" - -[dependencies] diff --git a/noir-projects/noir-protocol-circuits/crates/test/src/main.nr b/noir-projects/noir-protocol-circuits/crates/test/src/main.nr deleted file mode 100644 index 87a19715bc1..00000000000 --- a/noir-projects/noir-protocol-circuits/crates/test/src/main.nr +++ /dev/null @@ -1,23 +0,0 @@ -struct Array { - inner: [u32; N], -} - -struct Foo { - bar: Array, -} - -struct Bar { - baz: T, -} - -use dep::std::option::Option; - -fn main( - a: Bar>, - b: Foo<2>, - c: Foo<3>, - d: Bar>, - e: Bar, - f: Option>, - g: Option -) {} diff --git a/yarn-project/noir-protocol-circuits-types/src/index.ts b/yarn-project/noir-protocol-circuits-types/src/index.ts index d3f69ae3246..5a0feac0424 100644 --- a/yarn-project/noir-protocol-circuits-types/src/index.ts +++ b/yarn-project/noir-protocol-circuits-types/src/index.ts @@ -71,26 +71,22 @@ import { mapRootRollupInputsToNoir, mapRootRollupPublicInputsFromNoir, } from './type_conversion.js'; -import { type ParityBaseReturnType as BaseParityReturnType } from './types/parity_base_types.js'; -import { type ParityRootReturnType as RootParityReturnType } from './types/parity_root_types.js'; import { + type ParityBaseReturnType as BaseParityReturnType, + type RollupBaseReturnType as BaseRollupReturnType, type PrivateKernelInitInputType as InitInputType, type PrivateKernelInitReturnType as InitReturnType, -} from './types/private_kernel_init_types.js'; -import { type PrivateKernelInnerInputType as InnerInputType, type PrivateKernelInnerReturnType as InnerReturnType, -} from './types/private_kernel_inner_types.js'; -import { type PrivateKernelTailToPublicInputType as TailToPublicInputType } from './types/private_kernel_tail_to_public_types.js'; -import { + type RollupMergeReturnType as MergeRollupReturnType, + type PublicKernelAppLogicReturnType as PublicPublicPreviousReturnType, + type PublicKernelSetupReturnType as PublicSetupReturnType, + type ParityRootReturnType as RootParityReturnType, + type RollupRootReturnType as RootRollupReturnType, type PrivateKernelTailInputType as TailInputType, type PrivateKernelTailReturnType as TailReturnType, -} from './types/private_kernel_tail_types.js'; -import { type PublicKernelAppLogicReturnType as PublicPublicPreviousReturnType } from './types/public_kernel_app_logic_types.js'; -import { type PublicKernelSetupReturnType as PublicSetupReturnType } from './types/public_kernel_setup_types.js'; -import { type RollupBaseReturnType as BaseRollupReturnType } from './types/rollup_base_types.js'; -import { type RollupMergeReturnType as MergeRollupReturnType } from './types/rollup_merge_types.js'; -import { type RollupRootReturnType as RootRollupReturnType } from './types/rollup_root_types.js'; + type PrivateKernelTailToPublicInputType as TailToPublicInputType, +} from './types/index.js'; // TODO(Tom): This should be exported from noirc_abi /** diff --git a/yarn-project/noir-protocol-circuits-types/src/scripts/generate_ts_from_abi.ts b/yarn-project/noir-protocol-circuits-types/src/scripts/generate_ts_from_abi.ts index 323529366f9..fe88f185c36 100644 --- a/yarn-project/noir-protocol-circuits-types/src/scripts/generate_ts_from_abi.ts +++ b/yarn-project/noir-protocol-circuits-types/src/scripts/generate_ts_from_abi.ts @@ -283,19 +283,18 @@ const main = async () => { await fs.mkdir('./src/types', { recursive: true }); } + const allAbis = []; + for (const circuit of circuits) { const rawData = await fs.readFile(`./src/target/${circuit}.json`, 'utf-8'); const abiObj: NoirCompiledCircuit = JSON.parse(rawData); - - const generatedInterface = new TypingsGenerator([ - { - abi: abiObj.abi, - circuitName: pascalCase(circuit), - }, - ]).codegen(); - const outputFile = `./src/types/${circuit}_types.ts`; - await fs.writeFile(outputFile, generatedInterface); + allAbis.push({ + abi: abiObj.abi, + circuitName: pascalCase(circuit), + }); } + const interfaces = new TypingsGenerator(allAbis).codegen(); + await fs.writeFile('./src/types/index.ts', interfaces); }; try { diff --git a/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts b/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts index a891b6c775c..8ad1f00ef89 100644 --- a/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts +++ b/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts @@ -119,120 +119,104 @@ import { import { toBufferBE } from '@aztec/foundation/bigint-buffer'; import { type Tuple, mapTuple, toTruncField } from '@aztec/foundation/serialize'; -import { type BaseParityInputs as BaseParityInputsNoir } from './types/parity_base_types.js'; -import { - type RootParityInput as ParityRootParityInputNoir, - type RootParityInputs as RootParityInputsNoir, -} from './types/parity_root_types.js'; import { + type AppendOnlyTreeSnapshot as AppendOnlyTreeSnapshotNoir, + type ArchiveRootMembershipWitness as ArchiveRootMembershipWitnessNoir, + type BaseOrMergeRollupPublicInputs as BaseOrMergeRollupPublicInputsNoir, + type BaseParityInputs as BaseParityInputsNoir, + type BaseRollupInputs as BaseRollupInputsNoir, type CallContext as CallContextNoir, type CallRequest as CallRequestNoir, type CallerContext as CallerContextNoir, + type CombinedAccumulatedData as CombinedAccumulatedDataNoir, type CombinedConstantData as CombinedConstantDataNoir, + type ConstantRollupData as ConstantRollupDataNoir, + type ContentCommitment as ContentCommitmentNoir, + type Field, type FunctionData as FunctionDataNoir, type FunctionLeafMembershipWitness as FunctionLeafMembershipWitnessNoir, type FunctionSelector as FunctionSelectorNoir, type GasFees as GasFeesNoir, + type Gas as GasNoir, type GasSettings as GasSettingsNoir, + type GlobalVariables as GlobalVariablesNoir, + type GrumpkinPrivateKey as GrumpkinPrivateKeyNoir, + type Header as HeaderNoir, + type KernelCircuitPublicInputs as KernelCircuitPublicInputsNoir, + type KernelData as KernelDataNoir, type L2ToL1Message as L2ToL1MessageNoir, + type LeafDataReadHint as LeafDataReadHintNoir, type MaxBlockNumber as MaxBlockNumberNoir, + type MergeRollupInputs as MergeRollupInputsNoir, type AztecAddress as NoirAztecAddress, type EthAddress as NoirEthAddress, type Field as NoirField, type GrumpkinPoint as NoirPoint, type NoteHashContext as NoteHashContextNoir, + type NoteHashLeafPreimage as NoteHashLeafPreimageNoir, + type NoteHashMembershipWitness as NoteHashMembershipWitnessNoir, type NoteHash as NoteHashNoir, + type NoteHashReadRequestHints as NoteHashReadRequestHintsNoir, + type NoteHashSettledReadHint as NoteHashSettledReadHintNoir, type NullifierKeyValidationRequestContext as NullifierKeyValidationRequestContextNoir, type NullifierKeyValidationRequest as NullifierKeyValidationRequestNoir, + type NullifierLeafPreimage as NullifierLeafPreimageNoir, + type NullifierMembershipWitness as NullifierMembershipWitnessNoir, type Nullifier as NullifierNoir, + type NullifierNonExistentReadRequestHints as NullifierNonExistentReadRequestHintsNoir, + type NullifierNonMembershipHint as NullifierNonMembershipHintNoir, + type NullifierReadRequestHints as NullifierReadRequestHintsNoir, + type NullifierSettledReadHint as NullifierSettledReadHintNoir, + type ParityPublicInputs as ParityPublicInputsNoir, + type RootParityInput as ParityRootParityInputNoir, + type PartialStateReference as PartialStateReferenceNoir, + type PendingReadHint as PendingReadHintNoir, + type PreviousRollupData as PreviousRollupDataNoir, type PrivateAccumulatedData as PrivateAccumulatedDataNoir, type PrivateCallData as PrivateCallDataNoir, type PrivateCallStackItem as PrivateCallStackItemNoir, type PrivateCircuitPublicInputs as PrivateCircuitPublicInputsNoir, type PrivateKernelCircuitPublicInputs as PrivateKernelCircuitPublicInputsNoir, + type PrivateKernelData as PrivateKernelDataNoir, type PrivateKernelInitCircuitPrivateInputs as PrivateKernelInitCircuitPrivateInputsNoir, - type PublicDataRead as PublicDataReadNoir, - type ReadRequestContext as ReadRequestContextNoir, - type ReadRequest as ReadRequestNoir, - type RollupValidationRequests as RollupValidationRequestsNoir, - type SideEffect as SideEffectNoir, - type TxContext as TxContextNoir, - type TxRequest as TxRequestNoir, - type ValidationRequests as ValidationRequestsNoir, -} from './types/private_kernel_init_types.js'; -import { type PrivateKernelInnerCircuitPrivateInputs as PrivateKernelInnerCircuitPrivateInputsNoir, type PrivateKernelInnerHints as PrivateKernelInnerHintsNoir, -} from './types/private_kernel_inner_types.js'; -import { type PrivateKernelTailToPublicCircuitPrivateInputs as PrivateKernelTailToPublicCircuitPrivateInputsNoir } from './types/private_kernel_tail_to_public_types.js'; -import { - type CombinedAccumulatedData as CombinedAccumulatedDataNoir, - type Gas as GasNoir, - type GrumpkinPrivateKey as GrumpkinPrivateKeyNoir, - type NoteHashLeafPreimage as NoteHashLeafPreimageNoir, - type NoteHashMembershipWitness as NoteHashMembershipWitnessNoir, - type NoteHashReadRequestHints as NoteHashReadRequestHintsNoir, - type NoteHashSettledReadHint as NoteHashSettledReadHintNoir, - type NullifierReadRequestHints as NullifierReadRequestHintsNoir, - type NullifierSettledReadHint as NullifierSettledReadHintNoir, - type PendingReadHint as PendingReadHintNoir, - type PrivateKernelData as PrivateKernelDataNoir, type PrivateKernelTailCircuitPrivateInputs as PrivateKernelTailCircuitPrivateInputsNoir, type PrivateKernelTailHints as PrivateKernelTailHintsNoir, type PrivateKernelTailOutputs as PrivateKernelTailOutputsNoir, - type ReadRequestStatus as ReadRequestStatusNoir, -} from './types/private_kernel_tail_types.js'; -import { + type PrivateKernelTailToPublicCircuitPrivateInputs as PrivateKernelTailToPublicCircuitPrivateInputsNoir, type PublicAccumulatedData as PublicAccumulatedDataNoir, - type PublicKernelData as PublicKernelDataNoir, -} from './types/public_kernel_app_logic_types.js'; -import { type PublicCallData as PublicCallDataNoir, type PublicCallStackItem as PublicCallStackItemNoir, type PublicCircuitPublicInputs as PublicCircuitPublicInputsNoir, - type PublicKernelCircuitPublicInputs as PublicKernelCircuitPublicInputsNoir, - type PublicKernelSetupCircuitPrivateInputs as PublicKernelSetupCircuitPrivateInputsNoir, - type StorageRead as StorageReadNoir, - type StorageUpdateRequest as StorageUpdateRequestNoir, -} from './types/public_kernel_setup_types.js'; -import { - type LeafDataReadHint as LeafDataReadHintNoir, - type NullifierNonExistentReadRequestHints as NullifierNonExistentReadRequestHintsNoir, - type NullifierNonMembershipHint as NullifierNonMembershipHintNoir, type PublicDataHint as PublicDataHintNoir, - type PublicDataReadRequestHints as PublicDataReadRequestHintsNoir, - type PublicDataUpdateRequest as PublicDataUpdateRequestNoir, - type PublicKernelTailCircuitPrivateInputs as PublicKernelTailCircuitPrivateInputsNoir, -} from './types/public_kernel_tail_types.js'; -import { - type ArchiveRootMembershipWitness as ArchiveRootMembershipWitnessNoir, - type BaseRollupInputs as BaseRollupInputsNoir, - type KernelCircuitPublicInputs as KernelCircuitPublicInputsNoir, - type KernelData as KernelDataNoir, - type NullifierLeafPreimage as NullifierLeafPreimageNoir, - type NullifierMembershipWitness as NullifierMembershipWitnessNoir, type PublicDataMembershipWitness as PublicDataMembershipWitnessNoir, + type PublicDataRead as PublicDataReadNoir, + type PublicDataReadRequestHints as PublicDataReadRequestHintsNoir, type PublicDataTreeLeaf as PublicDataTreeLeafNoir, type PublicDataTreeLeafPreimage as PublicDataTreeLeafPreimageNoir, - type StateDiffHints as StateDiffHintsNoir, -} from './types/rollup_base_types.js'; -import { type MergeRollupInputs as MergeRollupInputsNoir } from './types/rollup_merge_types.js'; -import { - type AppendOnlyTreeSnapshot as AppendOnlyTreeSnapshotNoir, - type BaseOrMergeRollupPublicInputs as BaseOrMergeRollupPublicInputsNoir, - type ConstantRollupData as ConstantRollupDataNoir, - type ContentCommitment as ContentCommitmentNoir, - type Field, - type GlobalVariables as GlobalVariablesNoir, - type Header as HeaderNoir, - type ParityPublicInputs as ParityPublicInputsNoir, - type PartialStateReference as PartialStateReferenceNoir, - type PreviousRollupData as PreviousRollupDataNoir, + type PublicDataUpdateRequest as PublicDataUpdateRequestNoir, + type PublicKernelCircuitPublicInputs as PublicKernelCircuitPublicInputsNoir, + type PublicKernelData as PublicKernelDataNoir, + type PublicKernelSetupCircuitPrivateInputs as PublicKernelSetupCircuitPrivateInputsNoir, + type PublicKernelTailCircuitPrivateInputs as PublicKernelTailCircuitPrivateInputsNoir, + type ReadRequestContext as ReadRequestContextNoir, + type ReadRequest as ReadRequestNoir, + type ReadRequestStatus as ReadRequestStatusNoir, + type RollupValidationRequests as RollupValidationRequestsNoir, + type RootParityInputs as RootParityInputsNoir, type RootRollupInputs as RootRollupInputsNoir, type RootRollupParityInput as RootRollupParityInputNoir, type RootRollupPublicInputs as RootRollupPublicInputsNoir, + type SideEffect as SideEffectNoir, + type StateDiffHints as StateDiffHintsNoir, type StateReference as StateReferenceNoir, -} from './types/rollup_root_types.js'; + type StorageRead as StorageReadNoir, + type StorageUpdateRequest as StorageUpdateRequestNoir, + type TxContext as TxContextNoir, + type TxRequest as TxRequestNoir, + type ValidationRequests as ValidationRequestsNoir, +} from './types/index.js'; /* eslint-disable camelcase */ From 262ede980b0ead06739f5775d2ea72cd9256f70d Mon Sep 17 00:00:00 2001 From: sirasistant Date: Tue, 7 May 2024 09:50:59 +0000 Subject: [PATCH 4/9] added some comments --- .../noir-protocol-circuits-types/package.json | 2 +- .../src/scripts/abi_type_with_generics.ts | 22 ++++++++++++- .../src/scripts/demonomorphizer.ts | 33 +++++++++++++++++-- .../src/scripts/generate_ts_from_abi.ts | 1 - 4 files changed, 52 insertions(+), 6 deletions(-) diff --git a/yarn-project/noir-protocol-circuits-types/package.json b/yarn-project/noir-protocol-circuits-types/package.json index 50b836ba0e8..83f918856b4 100644 --- a/yarn-project/noir-protocol-circuits-types/package.json +++ b/yarn-project/noir-protocol-circuits-types/package.json @@ -52,6 +52,7 @@ "@noir-lang/acvm_js": "portal:../../noir/packages/acvm_js", "@noir-lang/noirc_abi": "portal:../../noir/packages/noirc_abi", "@noir-lang/types": "portal:../../noir/packages/types", + "change-case": "^5.4.4", "tslib": "^2.4.0" }, "devDependencies": { @@ -61,7 +62,6 @@ "@jest/globals": "^29.5.0", "@types/jest": "^29.5.0", "@types/node": "^18.7.23", - "change-case": "^5.4.4", "jest": "^29.5.0", "levelup": "^5.1.1", "memdown": "^6.1.1", diff --git a/yarn-project/noir-protocol-circuits-types/src/scripts/abi_type_with_generics.ts b/yarn-project/noir-protocol-circuits-types/src/scripts/abi_type_with_generics.ts index 0e7cc1d3d66..20bc056d7fe 100644 --- a/yarn-project/noir-protocol-circuits-types/src/scripts/abi_type_with_generics.ts +++ b/yarn-project/noir-protocol-circuits-types/src/scripts/abi_type_with_generics.ts @@ -1,10 +1,18 @@ import { type AbiType } from '@aztec/foundation/abi'; +/** + * Represents a binding to a generic. + */ export class BindingId { constructor(public id: number, public isNumeric: boolean) {} } -export type StructType = { path: string; fields: { name: string; type: AbiTypeWithGenerics }[]; generics: BindingId[] }; +export type StructType = { + path: string; + fields: { name: string; type: AbiTypeWithGenerics }[]; + /** The generics of the struct, bound to the fields */ + generics: BindingId[]; +}; export type StringType = { kind: 'string'; @@ -30,6 +38,7 @@ export type Tuple = { export type Struct = { kind: 'struct'; structType: StructType; + /** The arguments are the concrete instantiation of the generics in the struct type. */ args: AbiTypeWithGenerics[]; }; @@ -44,6 +53,10 @@ export type AbiTypeWithGenerics = | Tuple | Struct; +/** + * Maps an ABI type to an ABI type with generics. + * This performs pure type conversion, and does not generate any bindings. + */ export function mapAbiTypeToAbiTypeWithGenerics(abiType: AbiType): AbiTypeWithGenerics { switch (abiType.kind) { case 'field': @@ -80,6 +93,10 @@ export function mapAbiTypeToAbiTypeWithGenerics(abiType: AbiType): AbiTypeWithGe } } +/** + * Finds the structs in an ABI type. + * This won't explore nested structs. + */ export function findStructsInType(abiType: AbiTypeWithGenerics): Struct[] { switch (abiType.kind) { case 'field': @@ -99,6 +116,9 @@ export function findStructsInType(abiType: AbiTypeWithGenerics): Struct[] { } } +/** + * Finds all the structs in an ABI type, including nested structs. + */ export function findAllStructsInType(abiType: AbiTypeWithGenerics): Struct[] { let allStructs: Struct[] = []; let lastStructs = findStructsInType(abiType); diff --git a/yarn-project/noir-protocol-circuits-types/src/scripts/demonomorphizer.ts b/yarn-project/noir-protocol-circuits-types/src/scripts/demonomorphizer.ts index a7045c14d99..afa767d522f 100644 --- a/yarn-project/noir-protocol-circuits-types/src/scripts/demonomorphizer.ts +++ b/yarn-project/noir-protocol-circuits-types/src/scripts/demonomorphizer.ts @@ -11,14 +11,20 @@ import { findStructsInType, } from './abi_type_with_generics.js'; +/** + * Demonomorphizes a list of ABI types adding generics to structs. + * Since monomorphization of the generics destroys information, this process is not guaranteed to return the original structure. + * However, it should succesfully unify all struct types that share the same name and field names. + */ export class Demonomorphizer { private variantsMap: Map; private visitedStructs: Map; private lastBindingId = 0; - public static demonomorphize( - abiTypes: AbiTypeWithGenerics[], // Mutates passed in types - ) { + /** + * Demonomorphizes the passed in ABI types, mutating them. + */ + public static demonomorphize(abiTypes: AbiTypeWithGenerics[]) { new Demonomorphizer(abiTypes); } @@ -30,6 +36,10 @@ export class Demonomorphizer { this.demonomorphizeStructs(); } + /** + * Finds all the variants of the structs in the types. + * A variant is every use of a struct with the same name and fields. + */ private fillVariantsMap() { const allStructs = this.types.flatMap(findAllStructsInType); for (const struct of allStructs) { @@ -49,6 +59,11 @@ export class Demonomorphizer { } } + /** + * Demononomorphizes a struct, by demonomorphizing its dependencies first. + * Then it'll unify the types of the variants generating a unique generic type. + * It'll also generate args that instantiate the generic type with the concrete arguments for each variant. + */ private demonomorphizeStruct(struct: Struct) { const id = Demonomorphizer.buildIdForStruct(struct.structType); if (this.visitedStructs.has(id)) { @@ -77,6 +92,10 @@ export class Demonomorphizer { this.visitedStructs.set(id, mappedStructType); } + /** + * Tries to unify the types of a set of variants recursively. + * Unification will imply replacing some properties with bindings and pushing bindings to the generics of the struct. + */ private unifyTypes( types: AbiTypeWithGenerics[], generics: BindingId[], // Mutates generics adding new bindings @@ -161,8 +180,12 @@ export class Demonomorphizer { const structs = types as Struct[]; const ids = new Set(structs.map(struct => Demonomorphizer.buildIdForStruct(struct.structType))); if (ids.size > 1) { + // If the types are different structs, we can only unify them by creating a new binding. + // For example, if we have a struct A { x: u32 } and a struct A { x: Field }, the only possible unification is A { x: T } return this.buildBindingAndPushToVariants(types, generics, variants); } else { + // If the types are the same struct, we must unify the arguments to the struct. + // For example, if we have A and A, we need to unify to A and push T to the generics of the struct type. const newStruct = structuredClone(structs[0]); if (!structs.every(struct => struct.args.length === structs[0].args.length)) { @@ -192,6 +215,10 @@ export class Demonomorphizer { } } + /** + * We consider a struct to be the same if it has the same name and field names. + * Structs with the same id will be unified into a single type by the demonomorphizer. + */ public static buildIdForStruct(struct: StructType): string { const name = struct.path.split('::').pop()!; const fields = struct.fields.map(field => field.name).join(','); diff --git a/yarn-project/noir-protocol-circuits-types/src/scripts/generate_ts_from_abi.ts b/yarn-project/noir-protocol-circuits-types/src/scripts/generate_ts_from_abi.ts index fe88f185c36..d0a7ef45d04 100644 --- a/yarn-project/noir-protocol-circuits-types/src/scripts/generate_ts_from_abi.ts +++ b/yarn-project/noir-protocol-circuits-types/src/scripts/generate_ts_from_abi.ts @@ -273,7 +273,6 @@ const circuits = [ 'rollup_base', 'rollup_merge', 'rollup_root', - 'test', ]; const main = async () => { From 455390291200a4ccaf3bc7cd842b37817e5d7dd9 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Tue, 7 May 2024 09:58:16 +0000 Subject: [PATCH 5/9] chore: more docs --- .../src/scripts/generate_ts_from_abi.ts | 32 +++++++++++++++---- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/yarn-project/noir-protocol-circuits-types/src/scripts/generate_ts_from_abi.ts b/yarn-project/noir-protocol-circuits-types/src/scripts/generate_ts_from_abi.ts index d0a7ef45d04..c948939a196 100644 --- a/yarn-project/noir-protocol-circuits-types/src/scripts/generate_ts_from_abi.ts +++ b/yarn-project/noir-protocol-circuits-types/src/scripts/generate_ts_from_abi.ts @@ -64,6 +64,9 @@ function getLastComponentOfPath(str: string): string { return lastPart; } +/** + * Replaces a numeric binding with the corresponding generics name or the actual value. + */ function replaceNumericBinding(id: number | BindingId, genericsNameMap: Map): string { if (typeof id === 'number') { return id.toString(); @@ -73,16 +76,21 @@ function replaceNumericBinding(id: number | BindingId, genericsNameMap: Map(); + /** All the types in the ABIs */ private allTypes: AbiTypeWithGenerics[] = []; - private monomorphizedAbis: { + /** The demonomorphized ABIs of the circuits */ + private demonomorphizedAbis: { circuitName: string; params: { name: string; type: AbiTypeWithGenerics }[]; returnType?: AbiTypeWithGenerics; }[] = []; + /** Maps struct id to name for structs with the same name and different field sets */ private structIdToTsName = new Map(); + /** Collect all the primitives used in the types to add them to the codegen */ + private primitiveTypesUsed = new Map(); constructor(circuits: { abi: NoirFunctionAbi; circuitName: string }[]) { + // Map all the types used in the ABIs to the demonomorphized types for (const { abi, circuitName } of circuits) { const params = abi.parameters.map(param => { const type = mapAbiTypeToAbiTypeWithGenerics(param.type); @@ -92,11 +100,12 @@ class TypingsGenerator { if (abi.return_type) { const returnType = mapAbiTypeToAbiTypeWithGenerics(abi.return_type.abi_type); this.allTypes.push(returnType); - this.monomorphizedAbis.push({ circuitName, params, returnType }); + this.demonomorphizedAbis.push({ circuitName, params, returnType }); } else { - this.monomorphizedAbis.push({ circuitName, params }); + this.demonomorphizedAbis.push({ circuitName, params }); } } + // Demononmorphize the types Demonomorphizer.demonomorphize(this.allTypes); } @@ -116,6 +125,7 @@ class TypingsGenerator { private codegenAllStructs(): string { const allStructs = this.allTypes.flatMap(findAllStructsInType); + // First, deduplicate the structs used const structTypesToExport = new Map(); for (const struct of allStructs) { const id = Demonomorphizer.buildIdForStruct(struct.structType); @@ -125,6 +135,8 @@ class TypingsGenerator { structTypesToExport.set(id, struct.structType); } + // Then, we have to consider the case where we have struct with the same name but different fields. + // For those, we'll naively append a number to the name. const idsPerName = new Map(); for (const [id, structType] of structTypesToExport.entries()) { const name = getLastComponentOfPath(structType.path); @@ -141,7 +153,7 @@ class TypingsGenerator { }); } } - + // Now we can just generate the code for the structs let resultCode = ''; for (const structType of structTypesToExport.values()) { @@ -158,16 +170,19 @@ class TypingsGenerator { } private codegenStructType(structType: StructType): string { + // Generate names for the generic bindings. const genericsNameMap = new Map(); structType.generics.forEach((generic, index) => { genericsNameMap.set(generic.id, String.fromCharCode('A'.charCodeAt(0) + index)); }); + const name = this.getStructName(structType); const generics = structType.generics.length ? `<${structType.generics .map(generic => `${genericsNameMap.get(generic.id)}${generic.isNumeric ? ' extends number' : ''}`) .join(', ')}>` : ''; + let resultCode = `export interface ${name}${generics} {\n`; for (const field of structType.fields) { @@ -234,9 +249,13 @@ class TypingsGenerator { } } + /** + * Codegen all the interfaces for the circuits. + * For a circuit named Foo, we'll codegen FooInputType and FooReturnType. + */ private codegenAllInterfaces(): string { let resultCode = ''; - for (const { circuitName, params, returnType } of this.monomorphizedAbis) { + for (const { circuitName, params, returnType } of this.demonomorphizedAbis) { resultCode += this.codegenStructType({ path: `${circuitName}InputType`, fields: params, @@ -284,6 +303,7 @@ const main = async () => { const allAbis = []; + // Collect all abis for (const circuit of circuits) { const rawData = await fs.readFile(`./src/target/${circuit}.json`, 'utf-8'); const abiObj: NoirCompiledCircuit = JSON.parse(rawData); From 81fc4afe1167d792a1294b96438ce8dd1c80903f Mon Sep 17 00:00:00 2001 From: sirasistant Date: Tue, 7 May 2024 10:30:18 +0000 Subject: [PATCH 6/9] chore: undo adding tuples --- yarn-project/foundation/src/abi/abi.ts | 19 +------------------ yarn-project/foundation/src/abi/encoder.ts | 2 -- .../src/scripts/abi_type_with_generics.ts | 5 ----- 3 files changed, 1 insertion(+), 25 deletions(-) diff --git a/yarn-project/foundation/src/abi/abi.ts b/yarn-project/foundation/src/abi/abi.ts index 92bc10a482f..3dbe2dc7036 100644 --- a/yarn-project/foundation/src/abi/abi.ts +++ b/yarn-project/foundation/src/abi/abi.ts @@ -86,14 +86,7 @@ export interface BasicType { /** * A variable type. */ -export type AbiType = - | BasicType<'field'> - | BasicType<'boolean'> - | IntegerType - | ArrayType - | StringType - | StructType - | TupleType; +export type AbiType = BasicType<'field'> | BasicType<'boolean'> | IntegerType | ArrayType | StringType | StructType; /** * An integer type. @@ -147,16 +140,6 @@ export interface StructType extends BasicType<'struct'> { path: string; } -/** - * A tuple type. - */ -export interface TupleType extends BasicType<'tuple'> { - /** - * The fields of the tuple. - */ - fields: AbiType[]; -} - /** * Aztec.nr function types. */ diff --git a/yarn-project/foundation/src/abi/encoder.ts b/yarn-project/foundation/src/abi/encoder.ts index ca15ad524d1..119554935af 100644 --- a/yarn-project/foundation/src/abi/encoder.ts +++ b/yarn-project/foundation/src/abi/encoder.ts @@ -23,8 +23,6 @@ class ArgumentEncoder { return abiType.length * ArgumentEncoder.typeSize(abiType.type); case 'struct': return abiType.fields.reduce((acc, field) => acc + ArgumentEncoder.typeSize(field.type), 0); - case 'tuple': - return abiType.fields.reduce((acc, field) => acc + ArgumentEncoder.typeSize(field), 0); default: { const exhaustiveCheck: never = abiType; throw new Error(`Unhandled abi type: ${exhaustiveCheck}`); diff --git a/yarn-project/noir-protocol-circuits-types/src/scripts/abi_type_with_generics.ts b/yarn-project/noir-protocol-circuits-types/src/scripts/abi_type_with_generics.ts index 20bc056d7fe..c03dbb62a65 100644 --- a/yarn-project/noir-protocol-circuits-types/src/scripts/abi_type_with_generics.ts +++ b/yarn-project/noir-protocol-circuits-types/src/scripts/abi_type_with_generics.ts @@ -70,11 +70,6 @@ export function mapAbiTypeToAbiTypeWithGenerics(abiType: AbiType): AbiTypeWithGe length: abiType.length, type: mapAbiTypeToAbiTypeWithGenerics(abiType.type), }; - case 'tuple': - return { - kind: 'tuple', - fields: abiType.fields.map(field => mapAbiTypeToAbiTypeWithGenerics(field)), - }; case 'struct': { const structType = { path: abiType.path, From 5b94f7199dbc6c013424304a03adeaec3b9adc2c Mon Sep 17 00:00:00 2001 From: sirasistant Date: Tue, 7 May 2024 11:17:50 +0000 Subject: [PATCH 7/9] showcase generics in membership witnesses --- .../src/public_kernel_tail.nr | 24 +++--- .../src/note_hash_read_request_reset.nr | 18 ++--- .../src/types/public_data_hint.nr | 6 +- .../src/abis/previous_rollup_data.nr | 12 ++- .../rollup-lib/src/base/base_rollup_inputs.nr | 36 ++++----- .../rollup-lib/src/base/state_diff_hints.nr | 10 ++- .../crates/types/src/abis.nr | 3 - .../types/src/abis/membership_witness.nr | 77 ------------------- .../abis/private_kernel/private_call_data.nr | 10 +-- .../src/tests/fixtures/contract_functions.nr | 13 ++-- .../src/tests/private_call_data_builder.nr | 8 +- .../src/type_conversion.ts | 16 ++-- 12 files changed, 69 insertions(+), 164 deletions(-) delete mode 100644 noir-projects/noir-protocol-circuits/crates/types/src/abis/membership_witness.nr diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_tail.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_tail.nr index ffe93c8dfd0..bbc11756c56 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_tail.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_tail.nr @@ -57,7 +57,7 @@ impl PublicKernelTailCircuitPrivateInputs { hint.leaf_slot, exists_in_tree, hint.leaf_preimage, - MembershipWitness { leaf_index: hint.membership_witness.leaf_index, sibling_path: hint.membership_witness.sibling_path }, + hint.membership_witness, public_data_tree_root ); } @@ -115,19 +115,20 @@ mod tests { use dep::types::{ abis::{ kernel_circuit_public_inputs::KernelCircuitPublicInputs, kernel_data::PublicKernelData, - nullifier_leaf_preimage::NullifierLeafPreimage, membership_witness::PublicDataMembershipWitness + nullifier_leaf_preimage::NullifierLeafPreimage }, constants::{ MAX_NEW_NULLIFIERS_PER_TX, MAX_NULLIFIER_READ_REQUESTS_PER_TX, MAX_PUBLIC_DATA_HINTS, MAX_PUBLIC_DATA_READS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, NULLIFIER_TREE_HEIGHT, NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH, NULLIFIER_SUBTREE_HEIGHT, PUBLIC_DATA_SUBTREE_HEIGHT, PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH, PUBLIC_DATA_TREE_HEIGHT, MAX_ENCRYPTED_LOGS_PER_TX, - MAX_UNENCRYPTED_LOGS_PER_TX, + MAX_UNENCRYPTED_LOGS_PER_TX }, hash::{silo_nullifier, sha256_to_field}, public_data_tree_leaf_preimage::PublicDataTreeLeafPreimage, tests::{fixture_builder::FixtureBuilder, merkle_tree_utils::NonEmptyMerkleTree}, - partial_state_reference::PartialStateReference, utils::arrays::array_merge + partial_state_reference::PartialStateReference, utils::arrays::array_merge, + merkle_tree::MembershipWitness }; fn build_nullifier_tree() -> NonEmptyMerkleTree { @@ -264,7 +265,7 @@ mod tests { pub fn add_public_data_hint_for_settled_public_data(&mut self, leaf_index: u64) { let leaf_preimage = get_settled_public_data_leaves()[leaf_index]; - let membership_witness = PublicDataMembershipWitness { leaf_index: leaf_index as Field, sibling_path: self.public_data_tree.get_sibling_path(leaf_index) }; + let membership_witness = MembershipWitness { leaf_index: leaf_index as Field, sibling_path: self.public_data_tree.get_sibling_path(leaf_index) }; let hint = PublicDataHint { leaf_slot: leaf_preimage.slot, value: leaf_preimage.value, @@ -277,7 +278,7 @@ mod tests { pub fn add_public_data_hint_for_non_existent_public_data(&mut self, leaf_slot: Field, low_leaf_index: u64) { let leaf_preimage = get_settled_public_data_leaves()[low_leaf_index]; - let membership_witness = PublicDataMembershipWitness { + let membership_witness = MembershipWitness { leaf_index: low_leaf_index as Field, sibling_path: self.public_data_tree.get_sibling_path(low_leaf_index) }; @@ -360,18 +361,11 @@ mod tests { public_inputs.end.unencrypted_log_preimages_length, unencrypted_log_preimages_length + prev_unencrypted_log_preimages_length ); - let hash_bytes: [u8; MAX_ENCRYPTED_LOGS_PER_TX * 32] = prev_encrypted_logs_hash - .to_be_bytes(32) - .append(&[0; MAX_ENCRYPTED_LOGS_PER_TX * 32 - 32]) - .as_array(); + let hash_bytes: [u8; MAX_ENCRYPTED_LOGS_PER_TX * 32] = prev_encrypted_logs_hash.to_be_bytes(32).append(&[0; MAX_ENCRYPTED_LOGS_PER_TX * 32 - 32]).as_array(); let expected_encrypted_logs_hash = sha256_to_field(hash_bytes); assert_eq(public_inputs.end.encrypted_logs_hash, expected_encrypted_logs_hash); - let hash_bytes: [u8; MAX_UNENCRYPTED_LOGS_PER_TX * 32] = prev_unencrypted_logs_hash - .to_be_bytes(32) - .append(unencrypted_logs_hash.to_be_bytes(32)) - .append(&[0; MAX_UNENCRYPTED_LOGS_PER_TX * 32 - 64]) - .as_array(); + let hash_bytes: [u8; MAX_UNENCRYPTED_LOGS_PER_TX * 32] = prev_unencrypted_logs_hash.to_be_bytes(32).append(unencrypted_logs_hash.to_be_bytes(32)).append(&[0; MAX_UNENCRYPTED_LOGS_PER_TX * 32 - 64]).as_array(); let expected_unencrypted_logs_hash = sha256_to_field(hash_bytes); assert_eq(public_inputs.end.unencrypted_logs_hash, expected_unencrypted_logs_hash); } diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/note_hash_read_request_reset.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/note_hash_read_request_reset.nr index 8c40d7c2cf3..8bb008c5421 100644 --- a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/note_hash_read_request_reset.nr +++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/note_hash_read_request_reset.nr @@ -1,14 +1,14 @@ // This will be moved to a separate Read Request Reset Circuit. use crate::reset::read_request::{PendingReadHint, ReadRequestStatus, ReadValueHint, SettledReadHint}; use dep::types::{ - abis::{membership_witness::NoteHashMembershipWitness, note_hash_leaf_preimage::NoteHashLeafPreimage}, + abis::{note_hash_leaf_preimage::NoteHashLeafPreimage}, constants::{MAX_NOTE_HASH_READ_REQUESTS_PER_TX, NOTE_HASH_TREE_HEIGHT}, merkle_tree::MembershipWitness }; struct NoteHashSettledReadHint { read_request_index: u64, - membership_witness: NoteHashMembershipWitness, // Should be MembershipWitness when we can handle generics when converting to ts types. + membership_witness: MembershipWitness, leaf_preimage: NoteHashLeafPreimage, } @@ -20,7 +20,7 @@ impl ReadValueHint for NoteHashSettledReadHint { impl SettledReadHint for NoteHashSettledReadHint { fn membership_witness(self) -> MembershipWitness { - MembershipWitness { leaf_index: self.membership_witness.leaf_index, sibling_path: self.membership_witness.sibling_path } + self.membership_witness } fn leaf_preimage(self) -> NoteHashLeafPreimage { @@ -30,7 +30,7 @@ impl SettledReadHint for NoteHashSe fn nada(read_request_len: u64) -> Self { NoteHashSettledReadHint { read_request_index: read_request_len, - membership_witness: NoteHashMembershipWitness::empty(), + membership_witness: MembershipWitness::empty(), leaf_preimage: NoteHashLeafPreimage::empty() } } @@ -46,10 +46,10 @@ mod tests { use crate::note_hash_read_request_reset::NoteHashSettledReadHint; use crate::reset::read_request::{PendingReadHint, ReadRequestState, ReadRequestStatus, reset_read_requests}; use dep::types::{ - address::AztecAddress, + address::AztecAddress, merkle_tree::MembershipWitness, abis::{ - membership_witness::NoteHashMembershipWitness, note_hash::NoteHashContext, - note_hash_leaf_preimage::NoteHashLeafPreimage, read_request::ReadRequestContext + note_hash::NoteHashContext, note_hash_leaf_preimage::NoteHashLeafPreimage, + read_request::ReadRequestContext }, constants::NOTE_HASH_TREE_HEIGHT, hash::silo_note_hash, tests::merkle_tree_utils::NonEmptyMerkleTree @@ -108,12 +108,12 @@ mod tests { let hints = [ NoteHashSettledReadHint { read_request_index: 0, - membership_witness: NoteHashMembershipWitness { leaf_index: 1, sibling_path: tree.get_sibling_path(1) }, + membership_witness: MembershipWitness { leaf_index: 1, sibling_path: tree.get_sibling_path(1) }, leaf_preimage: leaf_preimages[1] }, NoteHashSettledReadHint { read_request_index: 3, - membership_witness: NoteHashMembershipWitness { leaf_index: 0, sibling_path: tree.get_sibling_path(0) }, + membership_witness: MembershipWitness { leaf_index: 0, sibling_path: tree.get_sibling_path(0) }, leaf_preimage: leaf_preimages[0] } ]; diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/types/public_data_hint.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/types/public_data_hint.nr index 28a3eb74cb0..2bd7316a9a9 100644 --- a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/types/public_data_hint.nr +++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/types/public_data_hint.nr @@ -1,14 +1,14 @@ use crate::reset::{mutable_data_read_request::LeafDataHint}; use dep::types::{ - abis::membership_witness::PublicDataMembershipWitness, - public_data_tree_leaf_preimage::PublicDataTreeLeafPreimage + public_data_tree_leaf_preimage::PublicDataTreeLeafPreimage, merkle_tree::MembershipWitness, + constants::PUBLIC_DATA_TREE_HEIGHT }; struct PublicDataHint { leaf_slot: Field, value: Field, override_counter: u32, - membership_witness: PublicDataMembershipWitness, // Should be MembershipWitness when we can handle generics when converting to ts types. + membership_witness: MembershipWitness, // Should be MembershipWitness when we can handle generics when converting to ts types. leaf_preimage: PublicDataTreeLeafPreimage, } diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/previous_rollup_data.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/previous_rollup_data.nr index aecee269f9e..07abf8e362c 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/previous_rollup_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/previous_rollup_data.nr @@ -1,9 +1,7 @@ use crate::abis::base_or_merge_rollup_public_inputs::BaseOrMergeRollupPublicInputs; use dep::types::{ - abis::membership_witness::VKMembershipWitness, - constants::ROLLUP_VK_TREE_HEIGHT, - mocked::{Proof, VerificationKey}, - traits::Empty + constants::ROLLUP_VK_TREE_HEIGHT, mocked::{Proof, VerificationKey}, traits::Empty, + merkle_tree::MembershipWitness }; struct PreviousRollupData{ @@ -11,7 +9,7 @@ struct PreviousRollupData{ proof : Proof, vk : VerificationKey, vk_index : u32, - vk_sibling_path : VKMembershipWitness, + vk_sibling_path : MembershipWitness, } impl Empty for PreviousRollupData { @@ -21,7 +19,7 @@ impl Empty for PreviousRollupData { proof : Proof::empty(), vk : VerificationKey::empty(), vk_index : 0 as u32, - vk_sibling_path : VKMembershipWitness::empty(), + vk_sibling_path : MembershipWitness::empty(), } } -} \ No newline at end of file +} diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/base_rollup_inputs.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/base_rollup_inputs.nr index 3df978857ad..238cc1dbd13 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/base_rollup_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/base_rollup_inputs.nr @@ -9,10 +9,9 @@ use crate::{ use dep::types::{ hash::sha256_to_field, abis::{ - append_only_tree_snapshot::AppendOnlyTreeSnapshot, - membership_witness::{ArchiveRootMembershipWitness, NullifierMembershipWitness, PublicDataMembershipWitness}, - nullifier_leaf_preimage::NullifierLeafPreimage, public_data_update_request::PublicDataUpdateRequest, - public_data_read::PublicDataRead, kernel_data::KernelData + append_only_tree_snapshot::AppendOnlyTreeSnapshot, nullifier_leaf_preimage::NullifierLeafPreimage, + public_data_update_request::PublicDataUpdateRequest, public_data_read::PublicDataRead, + kernel_data::KernelData }, constants::{ NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH, NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH, @@ -20,7 +19,7 @@ use dep::types::{ MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_PUBLIC_DATA_READS_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, NUM_ENCRYPTED_LOGS_HASHES_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, NUM_UNENCRYPTED_LOGS_HASHES_PER_TX, NULLIFIER_SUBTREE_HEIGHT, NULLIFIER_TREE_HEIGHT, PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH, - PUBLIC_DATA_SUBTREE_HEIGHT + PUBLIC_DATA_SUBTREE_HEIGHT, ARCHIVE_HEIGHT }, merkle_tree::{ append_only_tree, assert_check_membership, calculate_empty_tree_root, calculate_subtree_root, @@ -43,9 +42,9 @@ struct BaseRollupInputs { sorted_public_data_writes: [PublicDataTreeLeaf; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], sorted_public_data_writes_indexes: [u64; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], low_public_data_writes_preimages: [PublicDataTreeLeafPreimage; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], - low_public_data_writes_witnesses: [PublicDataMembershipWitness; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], + low_public_data_writes_witnesses: [MembershipWitness; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], - archive_root_membership_witness: ArchiveRootMembershipWitness, + archive_root_membership_witness: MembershipWitness, constants: ConstantRollupData, } @@ -148,7 +147,7 @@ impl BaseRollupInputs { self.state_diff_hints.nullifier_subtree_sibling_path, self.state_diff_hints.nullifier_predecessor_preimages, self.state_diff_hints.nullifier_predecessor_membership_witnesses.map( - |witness: NullifierMembershipWitness| { + |witness: MembershipWitness| { MembershipWitness { leaf_index: witness.leaf_index, sibling_path: witness.sibling_path, @@ -266,7 +265,7 @@ fn insert_public_data_update_requests( sorted_public_data_writes: [PublicDataTreeLeaf; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], sorted_public_data_writes_indexes: [u64; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], low_public_data_writes_preimages: [PublicDataTreeLeafPreimage; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], - low_public_data_writes_witnesses: [PublicDataMembershipWitness; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], + low_public_data_writes_witnesses: [MembershipWitness; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], public_data_writes_subtree_sibling_path: [Field; PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH] ) -> AppendOnlyTreeSnapshot { indexed_tree::batch_insert( @@ -277,7 +276,7 @@ fn insert_public_data_update_requests( public_data_writes_subtree_sibling_path, low_public_data_writes_preimages, low_public_data_writes_witnesses.map( - |witness: PublicDataMembershipWitness| { + |witness: MembershipWitness| { MembershipWitness { leaf_index: witness.leaf_index, sibling_path: witness.sibling_path, @@ -369,12 +368,11 @@ mod tests { use dep::types::{ abis::{ append_only_tree_snapshot::AppendOnlyTreeSnapshot, - membership_witness::{ArchiveRootMembershipWitness, NullifierMembershipWitness, PublicDataMembershipWitness}, nullifier_leaf_preimage::NullifierLeafPreimage, public_data_read::PublicDataRead, public_data_update_request::PublicDataUpdateRequest, kernel_data::KernelData, side_effect::SideEffect, accumulated_data::CombinedAccumulatedData }, - address::{AztecAddress, EthAddress}, + merkle_tree::MembershipWitness, address::{AztecAddress, EthAddress}, constants::{ ARCHIVE_HEIGHT, MAX_PUBLIC_DATA_READS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH, @@ -409,12 +407,12 @@ mod tests { snapshot: AppendOnlyTreeSnapshot, public_data_writes: BoundedVec<(u64, PublicDataTreeLeaf), 2>, mut pre_existing_public_data: [PublicDataTreeLeafPreimage; EXISTING_LEAVES] - ) -> ([Field; 35], [PublicDataTreeLeaf; 32], [u64; 32], [PublicDataTreeLeafPreimage; 32], [PublicDataMembershipWitness; 32], [PublicDataTreeLeafPreimage; EXISTING_LEAVES]) { + ) -> ([Field; 35], [PublicDataTreeLeaf; 32], [u64; 32], [PublicDataTreeLeafPreimage; 32], [MembershipWitness; 32], [PublicDataTreeLeafPreimage; EXISTING_LEAVES]) { let mut subtree_path = [0; PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH]; let mut sorted_public_data_writes = [PublicDataTreeLeaf::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX]; let mut sorted_public_data_writes_indexes = [0 as u64; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX]; let mut low_public_data_writes_preimages = [PublicDataTreeLeafPreimage::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX]; - let mut low_public_data_writes_witnesses = [PublicDataMembershipWitness::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX]; + let mut low_public_data_writes_witnesses = [MembershipWitness::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX]; let mut new_subtree = [PublicDataTreeLeafPreimage::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX]; for i in 0..MAX_PUBLIC_DATA_WRITES_PER_TEST { @@ -458,7 +456,7 @@ mod tests { }; } low_public_data_writes_preimages[i] = low_leaf; - low_public_data_writes_witnesses[i] = PublicDataMembershipWitness { + low_public_data_writes_witnesses[i] = MembershipWitness { leaf_index: low_leaf_index as Field, sibling_path: public_data_tree.get_sibling_path(low_leaf_index) }; @@ -526,9 +524,9 @@ mod tests { nullifier_tree: &mut NonEmptyMerkleTree, kernel_data: &mut KernelData, start_nullifier_tree_snapshot: AppendOnlyTreeSnapshot - ) -> ([NullifierLeafPreimage; MAX_NEW_NULLIFIERS_PER_TX], [NullifierMembershipWitness; MAX_NEW_NULLIFIERS_PER_TX], [Field; MAX_NEW_NULLIFIERS_PER_TX], [u64; MAX_NEW_NULLIFIERS_PER_TX]) { + ) -> ([NullifierLeafPreimage; MAX_NEW_NULLIFIERS_PER_TX], [MembershipWitness; MAX_NEW_NULLIFIERS_PER_TX], [Field; MAX_NEW_NULLIFIERS_PER_TX], [u64; MAX_NEW_NULLIFIERS_PER_TX]) { let mut nullifier_predecessor_preimages = [NullifierLeafPreimage::empty(); MAX_NEW_NULLIFIERS_PER_TX]; - let mut low_nullifier_membership_witness = [NullifierMembershipWitness::empty(); MAX_NEW_NULLIFIERS_PER_TX]; + let mut low_nullifier_membership_witness = [MembershipWitness::empty(); MAX_NEW_NULLIFIERS_PER_TX]; let sorted_new_nullifier_tuples = sort_high_to_low( self.new_nullifiers.storage.map(|insertion: NullifierInsertion| insertion.value), @@ -562,7 +560,7 @@ mod tests { let mut low_preimage = pre_existing_nullifiers[low_index]; nullifier_predecessor_preimages[i] = low_preimage; - low_nullifier_membership_witness[i] = NullifierMembershipWitness { + low_nullifier_membership_witness[i] = MembershipWitness { leaf_index: low_index as Field, sibling_path: nullifier_tree.get_sibling_path(low_index) }; @@ -687,7 +685,7 @@ mod tests { sorted_public_data_writes_indexes, low_public_data_writes_preimages, low_public_data_writes_witnesses, - archive_root_membership_witness: ArchiveRootMembershipWitness { leaf_index: 0, sibling_path: start_archive.get_sibling_path(0) }, + archive_root_membership_witness: MembershipWitness { leaf_index: 0, sibling_path: start_archive.get_sibling_path(0) }, constants: self.constants } } diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/state_diff_hints.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/state_diff_hints.nr index 9c7dd03d70d..6af5eb698af 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/state_diff_hints.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/state_diff_hints.nr @@ -1,14 +1,16 @@ use dep::types::{ - abis::{membership_witness::NullifierMembershipWitness, nullifier_leaf_preimage::NullifierLeafPreimage}, + abis::{nullifier_leaf_preimage::NullifierLeafPreimage}, constants::{ MAX_NEW_NULLIFIERS_PER_TX, NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH, - NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH, PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH -} + NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH, PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH, + NULLIFIER_TREE_HEIGHT +}, + merkle_tree::MembershipWitness }; struct StateDiffHints { nullifier_predecessor_preimages: [NullifierLeafPreimage; MAX_NEW_NULLIFIERS_PER_TX], - nullifier_predecessor_membership_witnesses: [NullifierMembershipWitness; MAX_NEW_NULLIFIERS_PER_TX], + nullifier_predecessor_membership_witnesses: [MembershipWitness; MAX_NEW_NULLIFIERS_PER_TX], sorted_nullifiers: [Field; MAX_NEW_NULLIFIERS_PER_TX], sorted_nullifier_indexes: [u64; MAX_NEW_NULLIFIERS_PER_TX], diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis.nr index 2d0566b9c0d..2c2a9325bcb 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis.nr @@ -6,9 +6,6 @@ mod function_selector; mod function_data; mod global_variables; - -mod membership_witness; - mod note_hash_leaf_preimage; mod nullifier_leaf_preimage; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/membership_witness.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/membership_witness.nr deleted file mode 100644 index e0dfc960f08..00000000000 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/membership_witness.nr +++ /dev/null @@ -1,77 +0,0 @@ -use crate::{ - constants::{ - FUNCTION_TREE_HEIGHT, NULLIFIER_TREE_HEIGHT, NOTE_HASH_TREE_HEIGHT, ROLLUP_VK_TREE_HEIGHT, - ARCHIVE_HEIGHT, PUBLIC_DATA_TREE_HEIGHT -}, - traits::Empty -}; - -// TODO(Kev): Instead of doing `MembershipWitness` we are forced -// to do this new struct because the typescript bindings generator -// does not have logic to monomorphize these properly. See the file named -// `typechain-type-alias` in the folder `bug-collecting-crate` -struct FunctionLeafMembershipWitness{ - leaf_index: Field, - sibling_path: [Field; FUNCTION_TREE_HEIGHT] -} - -struct VKMembershipWitness{ - leaf_index: Field, - sibling_path: [Field; ROLLUP_VK_TREE_HEIGHT] -} - -struct NullifierMembershipWitness{ - leaf_index: Field, - sibling_path: [Field; NULLIFIER_TREE_HEIGHT] -} - -struct PublicDataMembershipWitness{ - leaf_index: Field, - sibling_path: [Field; PUBLIC_DATA_TREE_HEIGHT] -} - -struct ArchiveRootMembershipWitness{ - leaf_index: Field, - sibling_path: [Field; ARCHIVE_HEIGHT] -} - -struct NoteHashMembershipWitness { - leaf_index: Field, - sibling_path: [Field; NOTE_HASH_TREE_HEIGHT], -} - -impl Empty for VKMembershipWitness { - fn empty() -> Self { - VKMembershipWitness { - leaf_index: 0, - sibling_path: [0; ROLLUP_VK_TREE_HEIGHT] - } - } -} - -impl Empty for NullifierMembershipWitness { - fn empty() -> Self { - NullifierMembershipWitness { - leaf_index: 0, - sibling_path: [0; NULLIFIER_TREE_HEIGHT] - } - } -} - -impl Empty for PublicDataMembershipWitness { - fn empty() -> Self { - PublicDataMembershipWitness { - leaf_index: 0, - sibling_path: [0; PUBLIC_DATA_TREE_HEIGHT] - } - } -} - -impl Empty for NoteHashMembershipWitness { - fn empty() -> Self { - NoteHashMembershipWitness { - leaf_index: 0, - sibling_path: [0; NOTE_HASH_TREE_HEIGHT] - } - } -} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel/private_call_data.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel/private_call_data.nr index e00c6c79a47..760189375dd 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel/private_call_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel/private_call_data.nr @@ -1,11 +1,9 @@ -use crate::abis::{ - call_request::CallRequest, private_call_stack_item::PrivateCallStackItem, - membership_witness::FunctionLeafMembershipWitness -}; +use crate::abis::{call_request::CallRequest, private_call_stack_item::PrivateCallStackItem}; use crate::address::{SaltedInitializationHash, PublicKeysHash, EthAddress}; use crate::contract_class_id::ContractClassId; use crate::mocked::{Proof, VerificationKey}; -use crate::constants::{MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL}; +use crate::constants::{MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, FUNCTION_TREE_HEIGHT}; +use crate::merkle_tree::membership::MembershipWitness; struct PrivateCallData { call_stack_item: PrivateCallStackItem, @@ -20,7 +18,7 @@ struct PrivateCallData { public_keys_hash: PublicKeysHash, contract_class_artifact_hash: Field, contract_class_public_bytecode_commitment: Field, - function_leaf_membership_witness: FunctionLeafMembershipWitness, + function_leaf_membership_witness: MembershipWitness, acir_hash: Field, } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixtures/contract_functions.nr b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixtures/contract_functions.nr index a5f7642811a..836e673b5e1 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixtures/contract_functions.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixtures/contract_functions.nr @@ -1,13 +1,12 @@ -use crate::abis::{ - function_data::FunctionData, function_selector::FunctionSelector, - membership_witness::FunctionLeafMembershipWitness -}; +use crate::abis::{function_data::FunctionData, function_selector::FunctionSelector}; +use crate::merkle_tree::membership::MembershipWitness; +use crate::constants::FUNCTION_TREE_HEIGHT; struct ContractFunction { data: FunctionData, vk_hash: Field, acir_hash: Field, - membership_witness: FunctionLeafMembershipWitness, + membership_witness: MembershipWitness, } // sibling_path taken from __snapshots__/noir_test_gen.test.ts.snap @@ -18,7 +17,7 @@ global default_private_function = ContractFunction { }, vk_hash: 0, acir_hash: 1111, - membership_witness: FunctionLeafMembershipWitness { + membership_witness: MembershipWitness { leaf_index: 0, sibling_path: [ 0x1e5cebe7a50c5c8fd1ebe19ed6bbf80f77819b12a2a28f334e895501e1cda574, @@ -37,7 +36,7 @@ global default_public_function = ContractFunction { }, vk_hash: 0, acir_hash: 3333, - membership_witness: FunctionLeafMembershipWitness { + membership_witness: MembershipWitness { leaf_index: 2, sibling_path: [ 0x2d72ef5ebb7c974e1f5a8bed092f1cf1bf0a0cb1eda28516221ca7e5811ecf15, diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/tests/private_call_data_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/tests/private_call_data_builder.nr index c1b266fd6a0..a4c6a52930e 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/tests/private_call_data_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/tests/private_call_data_builder.nr @@ -2,16 +2,16 @@ use crate::{ abis::{ gas_settings::GasSettings, call_request::{CallerContext, CallRequest}, private_call_stack_item::PrivateCallStackItem, function_data::FunctionData, - max_block_number::MaxBlockNumber, membership_witness::FunctionLeafMembershipWitness, - private_circuit_public_inputs::PrivateCircuitPublicInputs, + max_block_number::MaxBlockNumber, private_circuit_public_inputs::PrivateCircuitPublicInputs, private_kernel::private_call_data::PrivateCallData, side_effect::SideEffect }, + merkle_tree::membership::MembershipWitness, address::{AztecAddress, EthAddress, SaltedInitializationHash, PublicKeysHash}, mocked::{Proof, VerificationKey}, tests::{fixtures, private_circuit_public_inputs_builder::PrivateCircuitPublicInputsBuilder}, transaction::{tx_request::TxRequest, tx_context::TxContext} }; -use crate::constants::{MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL}; +use crate::constants::{MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, FUNCTION_TREE_HEIGHT}; struct PrivateCallDataBuilder { // Values of PrivateCallStackItem. @@ -28,7 +28,7 @@ struct PrivateCallDataBuilder { public_keys_hash: PublicKeysHash, contract_class_artifact_hash: Field, contract_class_public_bytecode_commitment: Field, - function_leaf_membership_witness: FunctionLeafMembershipWitness, + function_leaf_membership_witness: MembershipWitness, acir_hash: Field, gas_settings: GasSettings, } diff --git a/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts b/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts index 8ad1f00ef89..2e838925517 100644 --- a/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts +++ b/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts @@ -121,7 +121,6 @@ import { type Tuple, mapTuple, toTruncField } from '@aztec/foundation/serialize' import { type AppendOnlyTreeSnapshot as AppendOnlyTreeSnapshotNoir, - type ArchiveRootMembershipWitness as ArchiveRootMembershipWitnessNoir, type BaseOrMergeRollupPublicInputs as BaseOrMergeRollupPublicInputsNoir, type BaseParityInputs as BaseParityInputsNoir, type BaseRollupInputs as BaseRollupInputsNoir, @@ -134,7 +133,6 @@ import { type ContentCommitment as ContentCommitmentNoir, type Field, type FunctionData as FunctionDataNoir, - type FunctionLeafMembershipWitness as FunctionLeafMembershipWitnessNoir, type FunctionSelector as FunctionSelectorNoir, type GasFees as GasFeesNoir, type Gas as GasNoir, @@ -147,6 +145,7 @@ import { type L2ToL1Message as L2ToL1MessageNoir, type LeafDataReadHint as LeafDataReadHintNoir, type MaxBlockNumber as MaxBlockNumberNoir, + type MembershipWitness as MembershipWitnessNoir, type MergeRollupInputs as MergeRollupInputsNoir, type AztecAddress as NoirAztecAddress, type EthAddress as NoirEthAddress, @@ -154,14 +153,12 @@ import { type GrumpkinPoint as NoirPoint, type NoteHashContext as NoteHashContextNoir, type NoteHashLeafPreimage as NoteHashLeafPreimageNoir, - type NoteHashMembershipWitness as NoteHashMembershipWitnessNoir, type NoteHash as NoteHashNoir, type NoteHashReadRequestHints as NoteHashReadRequestHintsNoir, type NoteHashSettledReadHint as NoteHashSettledReadHintNoir, type NullifierKeyValidationRequestContext as NullifierKeyValidationRequestContextNoir, type NullifierKeyValidationRequest as NullifierKeyValidationRequestNoir, type NullifierLeafPreimage as NullifierLeafPreimageNoir, - type NullifierMembershipWitness as NullifierMembershipWitnessNoir, type Nullifier as NullifierNoir, type NullifierNonExistentReadRequestHints as NullifierNonExistentReadRequestHintsNoir, type NullifierNonMembershipHint as NullifierNonMembershipHintNoir, @@ -190,7 +187,6 @@ import { type PublicCallStackItem as PublicCallStackItemNoir, type PublicCircuitPublicInputs as PublicCircuitPublicInputsNoir, type PublicDataHint as PublicDataHintNoir, - type PublicDataMembershipWitness as PublicDataMembershipWitnessNoir, type PublicDataRead as PublicDataReadNoir, type PublicDataReadRequestHints as PublicDataReadRequestHintsNoir, type PublicDataTreeLeaf as PublicDataTreeLeafNoir, @@ -766,7 +762,7 @@ export function mapPrivateCallStackItemToNoir(privateCallStackItem: PrivateCallS */ function mapFunctionLeafMembershipWitnessToNoir( membershipWitness: MembershipWitness, -): FunctionLeafMembershipWitnessNoir { +): MembershipWitnessNoir { return { leaf_index: membershipWitness.leafIndex.toString(), sibling_path: mapTuple(membershipWitness.siblingPath, mapFieldToNoir), @@ -1943,7 +1939,7 @@ export function mapNullifierLeafPreimageToNoir( function mapNoteHashMembershipWitnessToNoir( membershipWitness: MembershipWitness, -): NoteHashMembershipWitnessNoir { +): MembershipWitnessNoir { return { leaf_index: membershipWitness.leafIndex.toString(), sibling_path: mapTuple(membershipWitness.siblingPath, mapFieldToNoir), @@ -1957,7 +1953,7 @@ function mapNoteHashMembershipWitnessToNoir( */ export function mapNullifierMembershipWitnessToNoir( membershipWitness: MembershipWitness, -): NullifierMembershipWitnessNoir { +): MembershipWitnessNoir { return { leaf_index: membershipWitness.leafIndex.toString(), sibling_path: mapTuple(membershipWitness.siblingPath, mapFieldToNoir), @@ -1969,7 +1965,7 @@ export function mapNullifierMembershipWitnessToNoir( */ export function mapPublicDataMembershipWitnessToNoir( membershipWitness: MembershipWitness, -): PublicDataMembershipWitnessNoir { +): MembershipWitnessNoir { return { leaf_index: membershipWitness.leafIndex.toString(), sibling_path: mapTuple(membershipWitness.siblingPath, mapFieldToNoir), @@ -1983,7 +1979,7 @@ export function mapPublicDataMembershipWitnessToNoir( */ export function mapArchiveRootMembershipWitnessToNoir( membershipWitness: MembershipWitness, -): ArchiveRootMembershipWitnessNoir { +): MembershipWitnessNoir { return { leaf_index: membershipWitness.leafIndex.toString(), sibling_path: mapTuple(membershipWitness.siblingPath, mapFieldToNoir), From 4c0c8674a648325790f0fdd5c3d19c6c73a8216c Mon Sep 17 00:00:00 2001 From: sirasistant Date: Tue, 7 May 2024 11:39:23 +0000 Subject: [PATCH 8/9] unify mapMembershipWitness --- .../src/type_conversion.ts | 270 +++++++----------- 1 file changed, 106 insertions(+), 164 deletions(-) diff --git a/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts b/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts index 2e838925517..ed2295e907c 100644 --- a/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts +++ b/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts @@ -1,5 +1,4 @@ import { - type ARCHIVE_HEIGHT, AggregationObject, AppendOnlyTreeSnapshot, AztecAddress, @@ -16,7 +15,6 @@ import { type ContractStorageRead, type ContractStorageUpdateRequest, EthAddress, - type FUNCTION_TREE_HEIGHT, Fr, FunctionData, FunctionSelector, @@ -119,99 +117,100 @@ import { import { toBufferBE } from '@aztec/foundation/bigint-buffer'; import { type Tuple, mapTuple, toTruncField } from '@aztec/foundation/serialize'; -import { - type AppendOnlyTreeSnapshot as AppendOnlyTreeSnapshotNoir, - type BaseOrMergeRollupPublicInputs as BaseOrMergeRollupPublicInputsNoir, - type BaseParityInputs as BaseParityInputsNoir, - type BaseRollupInputs as BaseRollupInputsNoir, - type CallContext as CallContextNoir, - type CallRequest as CallRequestNoir, - type CallerContext as CallerContextNoir, - type CombinedAccumulatedData as CombinedAccumulatedDataNoir, - type CombinedConstantData as CombinedConstantDataNoir, - type ConstantRollupData as ConstantRollupDataNoir, - type ContentCommitment as ContentCommitmentNoir, - type Field, - type FunctionData as FunctionDataNoir, - type FunctionSelector as FunctionSelectorNoir, - type GasFees as GasFeesNoir, - type Gas as GasNoir, - type GasSettings as GasSettingsNoir, - type GlobalVariables as GlobalVariablesNoir, - type GrumpkinPrivateKey as GrumpkinPrivateKeyNoir, - type Header as HeaderNoir, - type KernelCircuitPublicInputs as KernelCircuitPublicInputsNoir, - type KernelData as KernelDataNoir, - type L2ToL1Message as L2ToL1MessageNoir, - type LeafDataReadHint as LeafDataReadHintNoir, - type MaxBlockNumber as MaxBlockNumberNoir, - type MembershipWitness as MembershipWitnessNoir, - type MergeRollupInputs as MergeRollupInputsNoir, - type AztecAddress as NoirAztecAddress, - type EthAddress as NoirEthAddress, - type Field as NoirField, - type GrumpkinPoint as NoirPoint, - type NoteHashContext as NoteHashContextNoir, - type NoteHashLeafPreimage as NoteHashLeafPreimageNoir, - type NoteHash as NoteHashNoir, - type NoteHashReadRequestHints as NoteHashReadRequestHintsNoir, - type NoteHashSettledReadHint as NoteHashSettledReadHintNoir, - type NullifierKeyValidationRequestContext as NullifierKeyValidationRequestContextNoir, - type NullifierKeyValidationRequest as NullifierKeyValidationRequestNoir, - type NullifierLeafPreimage as NullifierLeafPreimageNoir, - type Nullifier as NullifierNoir, - type NullifierNonExistentReadRequestHints as NullifierNonExistentReadRequestHintsNoir, - type NullifierNonMembershipHint as NullifierNonMembershipHintNoir, - type NullifierReadRequestHints as NullifierReadRequestHintsNoir, - type NullifierSettledReadHint as NullifierSettledReadHintNoir, - type ParityPublicInputs as ParityPublicInputsNoir, - type RootParityInput as ParityRootParityInputNoir, - type PartialStateReference as PartialStateReferenceNoir, - type PendingReadHint as PendingReadHintNoir, - type PreviousRollupData as PreviousRollupDataNoir, - type PrivateAccumulatedData as PrivateAccumulatedDataNoir, - type PrivateCallData as PrivateCallDataNoir, - type PrivateCallStackItem as PrivateCallStackItemNoir, - type PrivateCircuitPublicInputs as PrivateCircuitPublicInputsNoir, - type PrivateKernelCircuitPublicInputs as PrivateKernelCircuitPublicInputsNoir, - type PrivateKernelData as PrivateKernelDataNoir, - type PrivateKernelInitCircuitPrivateInputs as PrivateKernelInitCircuitPrivateInputsNoir, - type PrivateKernelInnerCircuitPrivateInputs as PrivateKernelInnerCircuitPrivateInputsNoir, - type PrivateKernelInnerHints as PrivateKernelInnerHintsNoir, - type PrivateKernelTailCircuitPrivateInputs as PrivateKernelTailCircuitPrivateInputsNoir, - type PrivateKernelTailHints as PrivateKernelTailHintsNoir, - type PrivateKernelTailOutputs as PrivateKernelTailOutputsNoir, - type PrivateKernelTailToPublicCircuitPrivateInputs as PrivateKernelTailToPublicCircuitPrivateInputsNoir, - type PublicAccumulatedData as PublicAccumulatedDataNoir, - type PublicCallData as PublicCallDataNoir, - type PublicCallStackItem as PublicCallStackItemNoir, - type PublicCircuitPublicInputs as PublicCircuitPublicInputsNoir, - type PublicDataHint as PublicDataHintNoir, - type PublicDataRead as PublicDataReadNoir, - type PublicDataReadRequestHints as PublicDataReadRequestHintsNoir, - type PublicDataTreeLeaf as PublicDataTreeLeafNoir, - type PublicDataTreeLeafPreimage as PublicDataTreeLeafPreimageNoir, - type PublicDataUpdateRequest as PublicDataUpdateRequestNoir, - type PublicKernelCircuitPublicInputs as PublicKernelCircuitPublicInputsNoir, - type PublicKernelData as PublicKernelDataNoir, - type PublicKernelSetupCircuitPrivateInputs as PublicKernelSetupCircuitPrivateInputsNoir, - type PublicKernelTailCircuitPrivateInputs as PublicKernelTailCircuitPrivateInputsNoir, - type ReadRequestContext as ReadRequestContextNoir, - type ReadRequest as ReadRequestNoir, - type ReadRequestStatus as ReadRequestStatusNoir, - type RollupValidationRequests as RollupValidationRequestsNoir, - type RootParityInputs as RootParityInputsNoir, - type RootRollupInputs as RootRollupInputsNoir, - type RootRollupParityInput as RootRollupParityInputNoir, - type RootRollupPublicInputs as RootRollupPublicInputsNoir, - type SideEffect as SideEffectNoir, - type StateDiffHints as StateDiffHintsNoir, - type StateReference as StateReferenceNoir, - type StorageRead as StorageReadNoir, - type StorageUpdateRequest as StorageUpdateRequestNoir, - type TxContext as TxContextNoir, - type TxRequest as TxRequestNoir, - type ValidationRequests as ValidationRequestsNoir, +import type { + AppendOnlyTreeSnapshot as AppendOnlyTreeSnapshotNoir, + BaseOrMergeRollupPublicInputs as BaseOrMergeRollupPublicInputsNoir, + BaseParityInputs as BaseParityInputsNoir, + BaseRollupInputs as BaseRollupInputsNoir, + CallContext as CallContextNoir, + CallRequest as CallRequestNoir, + CallerContext as CallerContextNoir, + CombinedAccumulatedData as CombinedAccumulatedDataNoir, + CombinedConstantData as CombinedConstantDataNoir, + ConstantRollupData as ConstantRollupDataNoir, + ContentCommitment as ContentCommitmentNoir, + Field, + FixedLengthArray, + FunctionData as FunctionDataNoir, + FunctionSelector as FunctionSelectorNoir, + GasFees as GasFeesNoir, + Gas as GasNoir, + GasSettings as GasSettingsNoir, + GlobalVariables as GlobalVariablesNoir, + GrumpkinPrivateKey as GrumpkinPrivateKeyNoir, + Header as HeaderNoir, + KernelCircuitPublicInputs as KernelCircuitPublicInputsNoir, + KernelData as KernelDataNoir, + L2ToL1Message as L2ToL1MessageNoir, + LeafDataReadHint as LeafDataReadHintNoir, + MaxBlockNumber as MaxBlockNumberNoir, + MembershipWitness as MembershipWitnessNoir, + MergeRollupInputs as MergeRollupInputsNoir, + AztecAddress as NoirAztecAddress, + EthAddress as NoirEthAddress, + Field as NoirField, + GrumpkinPoint as NoirPoint, + NoteHashContext as NoteHashContextNoir, + NoteHashLeafPreimage as NoteHashLeafPreimageNoir, + NoteHash as NoteHashNoir, + NoteHashReadRequestHints as NoteHashReadRequestHintsNoir, + NoteHashSettledReadHint as NoteHashSettledReadHintNoir, + NullifierKeyValidationRequestContext as NullifierKeyValidationRequestContextNoir, + NullifierKeyValidationRequest as NullifierKeyValidationRequestNoir, + NullifierLeafPreimage as NullifierLeafPreimageNoir, + Nullifier as NullifierNoir, + NullifierNonExistentReadRequestHints as NullifierNonExistentReadRequestHintsNoir, + NullifierNonMembershipHint as NullifierNonMembershipHintNoir, + NullifierReadRequestHints as NullifierReadRequestHintsNoir, + NullifierSettledReadHint as NullifierSettledReadHintNoir, + ParityPublicInputs as ParityPublicInputsNoir, + RootParityInput as ParityRootParityInputNoir, + PartialStateReference as PartialStateReferenceNoir, + PendingReadHint as PendingReadHintNoir, + PreviousRollupData as PreviousRollupDataNoir, + PrivateAccumulatedData as PrivateAccumulatedDataNoir, + PrivateCallData as PrivateCallDataNoir, + PrivateCallStackItem as PrivateCallStackItemNoir, + PrivateCircuitPublicInputs as PrivateCircuitPublicInputsNoir, + PrivateKernelCircuitPublicInputs as PrivateKernelCircuitPublicInputsNoir, + PrivateKernelData as PrivateKernelDataNoir, + PrivateKernelInitCircuitPrivateInputs as PrivateKernelInitCircuitPrivateInputsNoir, + PrivateKernelInnerCircuitPrivateInputs as PrivateKernelInnerCircuitPrivateInputsNoir, + PrivateKernelInnerHints as PrivateKernelInnerHintsNoir, + PrivateKernelTailCircuitPrivateInputs as PrivateKernelTailCircuitPrivateInputsNoir, + PrivateKernelTailHints as PrivateKernelTailHintsNoir, + PrivateKernelTailOutputs as PrivateKernelTailOutputsNoir, + PrivateKernelTailToPublicCircuitPrivateInputs as PrivateKernelTailToPublicCircuitPrivateInputsNoir, + PublicAccumulatedData as PublicAccumulatedDataNoir, + PublicCallData as PublicCallDataNoir, + PublicCallStackItem as PublicCallStackItemNoir, + PublicCircuitPublicInputs as PublicCircuitPublicInputsNoir, + PublicDataHint as PublicDataHintNoir, + PublicDataRead as PublicDataReadNoir, + PublicDataReadRequestHints as PublicDataReadRequestHintsNoir, + PublicDataTreeLeaf as PublicDataTreeLeafNoir, + PublicDataTreeLeafPreimage as PublicDataTreeLeafPreimageNoir, + PublicDataUpdateRequest as PublicDataUpdateRequestNoir, + PublicKernelCircuitPublicInputs as PublicKernelCircuitPublicInputsNoir, + PublicKernelData as PublicKernelDataNoir, + PublicKernelSetupCircuitPrivateInputs as PublicKernelSetupCircuitPrivateInputsNoir, + PublicKernelTailCircuitPrivateInputs as PublicKernelTailCircuitPrivateInputsNoir, + ReadRequestContext as ReadRequestContextNoir, + ReadRequest as ReadRequestNoir, + ReadRequestStatus as ReadRequestStatusNoir, + RollupValidationRequests as RollupValidationRequestsNoir, + RootParityInputs as RootParityInputsNoir, + RootRollupInputs as RootRollupInputsNoir, + RootRollupParityInput as RootRollupParityInputNoir, + RootRollupPublicInputs as RootRollupPublicInputsNoir, + SideEffect as SideEffectNoir, + StateDiffHints as StateDiffHintsNoir, + StateReference as StateReferenceNoir, + StorageRead as StorageReadNoir, + StorageUpdateRequest as StorageUpdateRequestNoir, + TxContext as TxContextNoir, + TxRequest as TxRequestNoir, + ValidationRequests as ValidationRequestsNoir, } from './types/index.js'; /* eslint-disable camelcase */ @@ -755,20 +754,6 @@ export function mapPrivateCallStackItemToNoir(privateCallStackItem: PrivateCallS }; } -/** - * Maps a function leaf membership witness to a noir function leaf membership witness. - * @param membershipWitness - The membership witness. - * @returns The noir function leaf membership witness. - */ -function mapFunctionLeafMembershipWitnessToNoir( - membershipWitness: MembershipWitness, -): MembershipWitnessNoir { - return { - leaf_index: membershipWitness.leafIndex.toString(), - sibling_path: mapTuple(membershipWitness.siblingPath, mapFieldToNoir), - }; -} - /** * Maps a private call data to a noir private call data. * @param privateCallData - The private call data. @@ -781,9 +766,7 @@ export function mapPrivateCallDataToNoir(privateCallData: PrivateCallData): Priv public_call_stack: mapTuple(privateCallData.publicCallStack, mapCallRequestToNoir), proof: {}, vk: {}, - function_leaf_membership_witness: mapFunctionLeafMembershipWitnessToNoir( - privateCallData.functionLeafMembershipWitness, - ), + function_leaf_membership_witness: mapMembershipWitnessToNoir(privateCallData.functionLeafMembershipWitness), contract_class_artifact_hash: mapFieldToNoir(privateCallData.contractClassArtifactHash), contract_class_public_bytecode_commitment: mapFieldToNoir(privateCallData.contractClassPublicBytecodeCommitment), public_keys_hash: mapWrappedFieldToNoir(privateCallData.publicKeysHash), @@ -911,7 +894,7 @@ function mapNoteHashSettledReadHintToNoir( ): NoteHashSettledReadHintNoir { return { read_request_index: mapNumberToNoir(hint.readRequestIndex), - membership_witness: mapNoteHashMembershipWitnessToNoir(hint.membershipWitness), + membership_witness: mapMembershipWitnessToNoir(hint.membershipWitness), leaf_preimage: mapNoteHashLeafPreimageToNoir(hint.leafPreimage), }; } @@ -921,7 +904,7 @@ function mapNullifierSettledReadHintToNoir( ): NullifierSettledReadHintNoir { return { read_request_index: mapNumberToNoir(hint.readRequestIndex), - membership_witness: mapNullifierMembershipWitnessToNoir(hint.membershipWitness), + membership_witness: mapMembershipWitnessToNoir(hint.membershipWitness), leaf_preimage: mapNullifierLeafPreimageToNoir(hint.leafPreimage), }; } @@ -947,7 +930,7 @@ function mapNullifierNonMembershipHintToNoir( ): NullifierNonMembershipHintNoir { return { low_leaf_preimage: mapNullifierLeafPreimageToNoir(hint.leafPreimage), - membership_witness: mapNullifierMembershipWitnessToNoir(hint.membershipWitness), + membership_witness: mapMembershipWitnessToNoir(hint.membershipWitness), }; } @@ -967,7 +950,7 @@ function mapPublicDataHintToNoir(hint: PublicDataHint): PublicDataHintNoir { leaf_slot: mapFieldToNoir(hint.leafSlot), value: mapFieldToNoir(hint.value), override_counter: mapNumberToNoir(hint.overrideCounter), - membership_witness: mapPublicDataMembershipWitnessToNoir(hint.membershipWitness), + membership_witness: mapMembershipWitnessToNoir(hint.membershipWitness), leaf_preimage: mapPublicDataTreePreimageToNoir(hint.leafPreimage), }; } @@ -1937,52 +1920,11 @@ export function mapNullifierLeafPreimageToNoir( }; } -function mapNoteHashMembershipWitnessToNoir( - membershipWitness: MembershipWitness, -): MembershipWitnessNoir { - return { - leaf_index: membershipWitness.leafIndex.toString(), - sibling_path: mapTuple(membershipWitness.siblingPath, mapFieldToNoir), - }; -} - -/** - * Maps a nullifier membership witness to noir. - * @param membershipWitness - The nullifier membership witness. - * @returns The noir nullifier membership witness. - */ -export function mapNullifierMembershipWitnessToNoir( - membershipWitness: MembershipWitness, -): MembershipWitnessNoir { - return { - leaf_index: membershipWitness.leafIndex.toString(), - sibling_path: mapTuple(membershipWitness.siblingPath, mapFieldToNoir), - }; -} - -/** - * Maps a membership witness of the public data tree to noir. - */ -export function mapPublicDataMembershipWitnessToNoir( - membershipWitness: MembershipWitness, -): MembershipWitnessNoir { - return { - leaf_index: membershipWitness.leafIndex.toString(), - sibling_path: mapTuple(membershipWitness.siblingPath, mapFieldToNoir), - }; -} - -/** - * Maps a membership witness of the blocks tree to noir. - * @param membershipWitness - The membership witness. - * @returns The noir membership witness. - */ -export function mapArchiveRootMembershipWitnessToNoir( - membershipWitness: MembershipWitness, -): MembershipWitnessNoir { +function mapMembershipWitnessToNoir(witness: MembershipWitness): MembershipWitnessNoir { + const siblingPath = mapTuple(witness.siblingPath, mapFieldToNoir) as FixedLengthArray; return { - leaf_index: membershipWitness.leafIndex.toString(), - sibling_path: mapTuple(membershipWitness.siblingPath, mapFieldToNoir), + leaf_index: witness.leafIndex.toString(), + sibling_path: siblingPath, }; } @@ -2033,7 +1975,7 @@ export function mapStateDiffHintsToNoir(hints: StateDiffHints): StateDiffHintsNo nullifier_predecessor_preimages: mapTuple(hints.nullifierPredecessorPreimages, mapNullifierLeafPreimageToNoir), nullifier_predecessor_membership_witnesses: mapTuple( hints.nullifierPredecessorMembershipWitnesses, - mapNullifierMembershipWitnessToNoir, + (witness: MembershipWitness) => mapMembershipWitnessToNoir(witness), ), sorted_nullifiers: mapTuple(hints.sortedNullifiers, mapFieldToNoir), sorted_nullifier_indexes: mapTuple(hints.sortedNullifierIndexes, (index: number) => mapNumberToNoir(index)), @@ -2084,10 +2026,10 @@ export function mapBaseRollupInputsToNoir(inputs: BaseRollupInputs): BaseRollupI low_public_data_writes_witnesses: mapTuple( inputs.lowPublicDataWritesMembershipWitnesses, - mapPublicDataMembershipWitnessToNoir, + (witness: MembershipWitness) => mapMembershipWitnessToNoir(witness), ), - archive_root_membership_witness: mapArchiveRootMembershipWitnessToNoir(inputs.archiveRootMembershipWitness), + archive_root_membership_witness: mapMembershipWitnessToNoir(inputs.archiveRootMembershipWitness), constants: mapConstantRollupDataToNoir(inputs.constants), }; } From 8e04ac064e0ded9a9b32ceeda116d2143f10a022 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Tue, 7 May 2024 11:57:33 +0000 Subject: [PATCH 9/9] remove cloning --- .../src/scripts/demonomorphizer.ts | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/yarn-project/noir-protocol-circuits-types/src/scripts/demonomorphizer.ts b/yarn-project/noir-protocol-circuits-types/src/scripts/demonomorphizer.ts index afa767d522f..f2c513a329c 100644 --- a/yarn-project/noir-protocol-circuits-types/src/scripts/demonomorphizer.ts +++ b/yarn-project/noir-protocol-circuits-types/src/scripts/demonomorphizer.ts @@ -109,22 +109,22 @@ export class Demonomorphizer { case 'field': case 'boolean': case 'binding': - return structuredClone(types[0]); + return types[0]; case 'integer': { if (allDeepEqual(types)) { - return structuredClone(types[0]); + return types[0]; } else { return this.buildBindingAndPushToVariants(types, generics, variants); } } case 'string': { const strings = types as StringType[]; - const newString = structuredClone(strings[0]); - if (strings.every(string => string.length === newString.length)) { - return newString; + const unifiedString = strings[0]; + if (strings.every(string => string.length === unifiedString.length)) { + return unifiedString; } else { - const newStringType: StringType = newString; - newStringType.length = this.buildNumericBindingAndPushToVariants( + const unifiedStringType: StringType = unifiedString; + unifiedStringType.length = this.buildNumericBindingAndPushToVariants( strings.map(string => { if (typeof string.length !== 'number') { throw new Error('Trying to unify strings with bindings'); @@ -134,18 +134,18 @@ export class Demonomorphizer { generics, variants, ); - return newStringType; + return unifiedStringType; } } case 'array': { const arrays = types as ArrayType[]; - const newArrayType: ArrayType = structuredClone(arrays[0]); + const unifiedArrayType: ArrayType = arrays[0]; if ( !arrays.every(array => { - return array.length === newArrayType.length; + return array.length === unifiedArrayType.length; }) ) { - newArrayType.length = this.buildNumericBindingAndPushToVariants( + unifiedArrayType.length = this.buildNumericBindingAndPushToVariants( arrays.map(array => { if (typeof array.length !== 'number') { throw new Error('Trying to unify arrays with bindings'); @@ -157,24 +157,24 @@ export class Demonomorphizer { ); } - newArrayType.type = this.unifyTypes( + unifiedArrayType.type = this.unifyTypes( arrays.map(array => array.type), generics, variants, ); - return newArrayType; + return unifiedArrayType; } case 'tuple': { const tuples = types as Tuple[]; - const newTupleType: Tuple = structuredClone(tuples[0]); - for (let i = 0; i < newTupleType.fields.length; i++) { - newTupleType.fields[i] = this.unifyTypes( + const unifiedTupleType: Tuple = tuples[0]; + for (let i = 0; i < unifiedTupleType.fields.length; i++) { + unifiedTupleType.fields[i] = this.unifyTypes( tuples.map(tuple => tuple.fields[i]), generics, variants, ); } - return newTupleType; + return unifiedTupleType; } case 'struct': { const structs = types as Struct[]; @@ -186,23 +186,23 @@ export class Demonomorphizer { } else { // If the types are the same struct, we must unify the arguments to the struct. // For example, if we have A and A, we need to unify to A and push T to the generics of the struct type. - const newStruct = structuredClone(structs[0]); + const unifiedStruct = structs[0]; - if (!structs.every(struct => struct.args.length === structs[0].args.length)) { + if (!structs.every(struct => struct.args.length === unifiedStruct.args.length)) { throw new Error('Same struct with different number of args encountered'); } - for (let i = 0; i < newStruct.args.length; i++) { + for (let i = 0; i < unifiedStruct.args.length; i++) { const argTypes = structs.map(struct => struct.args[i]); - newStruct.args[i] = this.unifyTypes(argTypes, generics, variants); + unifiedStruct.args[i] = this.unifyTypes(argTypes, generics, variants); } - return newStruct; + return unifiedStruct; } } case 'constant': { const constants = types as Constant[]; if (constants.every(constant => constant.value === constants[0].value)) { - return structuredClone(constants[0]); + return constants[0]; } else { return this.buildBindingAndPushToVariants(types, generics, variants, true); }