diff --git a/package-lock.json b/package-lock.json index 1f7cbca..30e7602 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "test/fixture-projects/*" ], "dependencies": { - "@distributedlab/circom-parser": "0.2.0", + "@distributedlab/circom-parser": "0.2.2", "@solarity/zkit": "0.3.0", "@solarity/zktype": "0.4.2", "@wasmer/wasi": "0.12.0", @@ -358,7 +358,9 @@ } }, "node_modules/@distributedlab/circom-parser": { - "version": "0.2.0", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@distributedlab/circom-parser/-/circom-parser-0.2.2.tgz", + "integrity": "sha512-HXxtg+v/4GPAG5n4e55cjQtmUgumITok8s58L9yWGX14EmVwxbZ8jFeLR9W3rAGI0HTCBF4UemZKPocqVQetSQ==", "license": "MIT", "dependencies": { "antlr4": "4.13.1-patch-1", @@ -5180,6 +5182,10 @@ "resolved": "test/fixture-projects/hardhat-project-with-circuits", "link": true }, + "node_modules/hardhat-project-with-circuits-main-component": { + "resolved": "test/fixture-projects/hardhat-project-with-circuits-main-component", + "link": true + }, "node_modules/hardhat-project-with-complex-circuits": { "resolved": "test/fixture-projects/hardhat-project-with-complex-circuits", "link": true @@ -8950,6 +8956,9 @@ "test/fixture-projects/hardhat-project-with-circuits": { "version": "1.0.0" }, + "test/fixture-projects/hardhat-project-with-circuits-main-component": { + "version": "1.0.0" + }, "test/fixture-projects/hardhat-project-with-complex-circuits": { "version": "1.0.0" }, diff --git a/package.json b/package.json index 737eeea..44e01f6 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "node": ">=16" }, "dependencies": { - "@distributedlab/circom-parser": "0.2.0", + "@distributedlab/circom-parser": "0.2.2", "@solarity/zkit": "0.3.0", "@solarity/zktype": "0.4.2", "@wasmer/wasi": "0.12.0", diff --git a/src/core/dependencies/parser/CircomFilesParser.ts b/src/core/dependencies/parser/CircomFilesParser.ts index 074ee9a..287a13e 100644 --- a/src/core/dependencies/parser/CircomFilesParser.ts +++ b/src/core/dependencies/parser/CircomFilesParser.ts @@ -1,4 +1,4 @@ -import { CircomValueType, getCircomParser, ParserError } from "@distributedlab/circom-parser"; +import { buildVariableContext, CircomValueType, getCircomParser, ParserError } from "@distributedlab/circom-parser"; import { CircomFilesVisitor } from "./CircomFilesVisitor"; import { CircomTemplateInputsVisitor } from "./CircomTemplateInputsVisitor"; @@ -64,7 +64,7 @@ export class CircomFilesParser { const visitorErrors = circomFilesVisitor.errors.filter( (error) => error.type === ErrorType.InvalidPragmaVersion || - error.type === ErrorType.TemplateAlreadyUsed || + error.type === ErrorType.TemplateAlreadyVisited || error.type === ErrorType.FailedToResolveMainComponentParameter, ); @@ -96,10 +96,13 @@ export class CircomFilesParser { templateName: string, parameterValues: Record, ): Record { + const parsedFileData = circomResolvedFile.fileData.parsedFileData; + + const values: CircomValueType[] = Object.keys(parameterValues).map((key) => parameterValues[key]); const circomTemplateInputsVisitor = new CircomTemplateInputsVisitor( circomResolvedFile.absolutePath, - circomResolvedFile.fileData.parsedFileData.templates[templateName].context, - parameterValues, + parsedFileData.templates[templateName].context, + buildVariableContext(parsedFileData.templates[templateName].parameters, values), ); circomTemplateInputsVisitor.startParse(); diff --git a/src/core/dependencies/parser/CircomFilesVisitor.ts b/src/core/dependencies/parser/CircomFilesVisitor.ts index 00fbf12..395336b 100644 --- a/src/core/dependencies/parser/CircomFilesVisitor.ts +++ b/src/core/dependencies/parser/CircomFilesVisitor.ts @@ -63,7 +63,7 @@ export class CircomFilesVisitor extends CircomVisitor { visitTemplateDefinition = (ctx: TemplateDefinitionContext) => { if (ctx.ID().getText() in this.fileData.templates) { this.errors.push({ - type: ErrorType.TemplateAlreadyUsed, + type: ErrorType.TemplateAlreadyVisited, context: ctx, fileIdentifier: this.fileIdentifier, templateIdentifier: ctx.ID().getText(), diff --git a/src/core/dependencies/parser/CircomTemplateInputsVisitor.ts b/src/core/dependencies/parser/CircomTemplateInputsVisitor.ts index a6ff793..8b27579 100644 --- a/src/core/dependencies/parser/CircomTemplateInputsVisitor.ts +++ b/src/core/dependencies/parser/CircomTemplateInputsVisitor.ts @@ -11,7 +11,6 @@ import { IfWithFollowUpIfContext, ParserErrorItem, ParserRuleContext, - parseSimpleIdentifierList, PIdentifierStatementContext, PUnderscoreContext, SignalDeclarationContext, @@ -58,8 +57,6 @@ export class CircomTemplateInputsVisitor extends CircomVisitor { this.templateInputs = {}; this._vars = parameterValues; - - this._validateVariableContext(); } startParse = () => { @@ -561,25 +558,6 @@ export class CircomTemplateInputsVisitor extends CircomVisitor { }); }; - private _validateVariableContext() { - const templateParameters = parseSimpleIdentifierList(this.templateContext.simpleIdentifierList()); - - for (const parameter of templateParameters) { - if (this._vars[parameter] === undefined || this._vars[parameter] === null) { - this.errors.push({ - type: ErrorType.MissingTemplateParameterValue, - context: this.templateContext, - fileIdentifier: this.templateContext.ID().getText(), - message: `Missing value for parameter ${parameter} in template ${this.templateContext.ID().getText()}`, - }); - - continue; - } - - this._declaredVariables[parameter] = true; - } - } - private _resolveIdentifier(ctx: IdentifierContext, variableContext: VariableContext = {}): IdentifierObject[] | null { const baseName = ctx.ID().getText(); diff --git a/src/types/core/dependencies/parser/circom-files-visitor.ts b/src/types/core/dependencies/parser/circom-files-visitor.ts index af02521..259e563 100644 --- a/src/types/core/dependencies/parser/circom-files-visitor.ts +++ b/src/types/core/dependencies/parser/circom-files-visitor.ts @@ -7,7 +7,7 @@ import { export enum ErrorType { SignalDimensionResolution, - TemplateAlreadyUsed, + TemplateAlreadyVisited, InvalidPragmaVersion, FailedToResolveMainComponentParameter, InternalExpressionHelperError, diff --git a/test/fixture-projects/hardhat-project-with-circuits-main-component/.gitignore b/test/fixture-projects/hardhat-project-with-circuits-main-component/.gitignore new file mode 100644 index 0000000..5065f39 --- /dev/null +++ b/test/fixture-projects/hardhat-project-with-circuits-main-component/.gitignore @@ -0,0 +1,7 @@ +/cache +/artifacts + +generated-types +compilers +contracts/verifiers +zkit diff --git a/test/fixture-projects/hardhat-project-with-circuits-main-component/circuits/base/SomeCircuit.circom b/test/fixture-projects/hardhat-project-with-circuits-main-component/circuits/base/SomeCircuit.circom new file mode 100644 index 0000000..2b44970 --- /dev/null +++ b/test/fixture-projects/hardhat-project-with-circuits-main-component/circuits/base/SomeCircuit.circom @@ -0,0 +1,5 @@ +pragma circom 2.1.6; + +include "templates/SomeCircuit.circom"; + +component main {public [in1]} = SomeCircuit([5, 3, 2, 5], 3); diff --git a/test/fixture-projects/hardhat-project-with-circuits-main-component/circuits/base/templates/SomeCircuit.circom b/test/fixture-projects/hardhat-project-with-circuits-main-component/circuits/base/templates/SomeCircuit.circom new file mode 100644 index 0000000..ae6174d --- /dev/null +++ b/test/fixture-projects/hardhat-project-with-circuits-main-component/circuits/base/templates/SomeCircuit.circom @@ -0,0 +1,8 @@ +pragma circom 2.1.6; + +template SomeCircuit(p1, p2){ + signal input in1; + signal input in2[p1[1] * p1[0]][p1[3] * p1[2] * p2]; + + signal output out <== in1 * in2[0][0]; +} diff --git a/test/fixture-projects/hardhat-project-with-circuits-main-component/hardhat.config.ts b/test/fixture-projects/hardhat-project-with-circuits-main-component/hardhat.config.ts new file mode 100644 index 0000000..f94665d --- /dev/null +++ b/test/fixture-projects/hardhat-project-with-circuits-main-component/hardhat.config.ts @@ -0,0 +1,28 @@ +import { HardhatUserConfig } from "hardhat/config"; + +import config from "../hardhat.config"; + +const defaultConfig: HardhatUserConfig = { + ...config, + zkit: { + circuitsDir: "circuits", + compilationSettings: { + artifactsDir: "zkit/artifacts", + skipFiles: ["vendor"], + }, + setupSettings: { + contributionSettings: { + provingSystem: ["groth16"], + }, + ptauDir: "zkit/ptau", + ptauDownload: true, + }, + quiet: true, + verifiersSettings: { + verifiersDir: "contracts/verifiers", + }, + typesDir: "generated-types/zkit", + }, +}; + +export default defaultConfig; diff --git a/test/fixture-projects/hardhat-project-with-circuits-main-component/package.json b/test/fixture-projects/hardhat-project-with-circuits-main-component/package.json new file mode 100644 index 0000000..487edde --- /dev/null +++ b/test/fixture-projects/hardhat-project-with-circuits-main-component/package.json @@ -0,0 +1,8 @@ +{ + "name": "hardhat-project-with-circuits-main-component", + "version": "1.0.0", + "scripts": { + "compile": "hardhat compile --force", + "clean": "hardhat clean && rm -rf artifacts && rm -rf cache" + } +} diff --git a/test/unit/core/dependencies/file-parser.test.ts b/test/unit/core/dependencies/file-parser.test.ts index 95c72cd..84630a5 100644 --- a/test/unit/core/dependencies/file-parser.test.ts +++ b/test/unit/core/dependencies/file-parser.test.ts @@ -10,8 +10,9 @@ import { getNormalizedFullPath } from "@src/utils/path-utils"; import { CIRCUITS_COMPILE_CACHE_FILENAME } from "@src/constants"; import { createCircuitsCompileCache } from "@src/cache"; import { createReporter } from "@src/reporter"; -import { ResolvedFileData } from "@src/types/core"; +import { CircomResolvedFile, ResolvedFileData } from "@src/types/core"; import { getCircomParser, VariableContext } from "@distributedlab/circom-parser"; +import { BaseCacheType } from "@src/types/cache/base-cache"; describe("CircomFilesParser", () => { describe("parse", () => { @@ -120,6 +121,32 @@ describe("CircomFilesParser", () => { }); }); + describe("parse with resolution of main component", () => { + useEnvironment("with-circuits-main-component"); + + beforeEach("setup", async function () { + await this.hre.run({ scope: ZKIT_SCOPE_NAME, task: TASK_CIRCUITS_COMPILE }); + }); + + it("should correctly resolve the arguments for the main component", async function () { + const circuitPath = getNormalizedFullPath(this.hre.config.paths.root, "circuits/base/SomeCircuit.circom"); + // eslint-disable-next-line @typescript-eslint/no-var-requires + const cache: BaseCacheType = require( + getNormalizedFullPath(this.hre.config.paths.root, "cache/circuits-compile-cache.json"), + ); + + const signals = cache.files[circuitPath].fileData.mainComponentData!.signals; + + const signalIn1 = signals.find((signal) => signal.name === "in1")!; + const signalIn2 = signals.find((signal) => signal.name === "in2")!; + const signalOut = signals.find((signal) => signal.name === "out")!; + + expect(signalIn1.dimension).to.deep.equal([]); + expect(signalIn2.dimension).to.deep.equal([15, 30]); + expect(signalOut.dimension).to.deep.equal([]); + }); + }); + describe("invalid parse", () => { useEnvironment("with-complex-circuits");