From 89b55710797be97bcbdf1c4924f4f92251b8ccbe Mon Sep 17 00:00:00 2001 From: Christopher Dedominici <18092467+ChristopherDedominici@users.noreply.github.com> Date: Wed, 14 Feb 2024 23:08:52 +0100 Subject: [PATCH 01/12] add settings in the compiler options --- packages/hardhat-vyper/README.md | 15 +++- packages/hardhat-vyper/src/compiler.ts | 16 +++- packages/hardhat-vyper/src/index.ts | 34 ++++++-- packages/hardhat-vyper/src/types.ts | 6 ++ .../contracts/A.vy | 5 ++ .../hardhat.config.js | 15 ++++ .../contracts/A.vy | 5 ++ .../contracts/B.vy | 5 ++ .../hardhat.config.js | 21 +++++ packages/hardhat-vyper/test/tests.ts | 81 +++++++++++++++++++ 10 files changed, 193 insertions(+), 10 deletions(-) create mode 100644 packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings-failure/contracts/A.vy create mode 100644 packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings-failure/hardhat.config.js create mode 100644 packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings/contracts/A.vy create mode 100644 packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings/contracts/B.vy create mode 100644 packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings/hardhat.config.js diff --git a/packages/hardhat-vyper/README.md b/packages/hardhat-vyper/README.md index 050a932cf7..db5813b8e1 100644 --- a/packages/hardhat-vyper/README.md +++ b/packages/hardhat-vyper/README.md @@ -58,12 +58,23 @@ module.exports = { }; ``` -You can also configure multiple versions of the Vyper compiler: +You can also configure multiple versions of the Vyper compiler together with the compiler settings properties evmVersion (supported starting from Vyper 0.3.8) and optimize (supported starting from Vyper 0.3.10). ```js module.exports = { vyper: { - compilers: [{ version: "0.2.1" }, { version: "0.3.0" }], + compilers: [ + { + version: "0.2.1", + }, + { + version: "0.3.10", + settings: { + evmVersion: "paris", + optimize: "gas", + }, + }, + ], }, }; ``` diff --git a/packages/hardhat-vyper/src/compiler.ts b/packages/hardhat-vyper/src/compiler.ts index bf5f5b211f..7242e660ba 100644 --- a/packages/hardhat-vyper/src/compiler.ts +++ b/packages/hardhat-vyper/src/compiler.ts @@ -1,4 +1,5 @@ import { exec } from "child_process"; +import { VyperSettings } from "./types"; export class Compiler { constructor(private _pathToVyper: string) {} @@ -7,10 +8,21 @@ export class Compiler { * * @param inputPaths array of paths to contracts to be compiled */ - public async compile(inputPaths: string[]) { + public async compile(inputPaths: string[], settings?: VyperSettings) { const output: string = await new Promise((resolve, reject) => { + let settingsStr = + settings?.evmVersion !== undefined + ? `--evm-version ${settings.evmVersion} ` + : ""; + settingsStr += + settings?.optimize !== undefined + ? `--optimize ${String(settings.optimize)} ` + : ""; + const process = exec( - `${this._pathToVyper} -f combined_json ${inputPaths.join(" ")}`, + `${this._pathToVyper} ${settingsStr} -f combined_json ${inputPaths.join( + " " + )}`, { maxBuffer: 1024 * 1024 * 500, }, diff --git a/packages/hardhat-vyper/src/index.ts b/packages/hardhat-vyper/src/index.ts index 4692a5675e..a3cd024570 100644 --- a/packages/hardhat-vyper/src/index.ts +++ b/packages/hardhat-vyper/src/index.ts @@ -1,7 +1,7 @@ import type { Artifacts as ArtifactsImpl } from "hardhat/internal/artifacts"; import type { Artifacts } from "hardhat/types/artifacts"; import type { VyperFilesCache as VyperFilesCacheT } from "./cache"; -import type { VyperOutput, VyperBuild } from "./types"; +import type { VyperOutput, VyperBuild, VyperSettings } from "./types"; import type { ResolvedFile } from "./resolver"; import * as os from "os"; @@ -188,13 +188,18 @@ subtask(TASK_COMPILE_VYPER_RUN_BINARY) async ({ inputPaths, vyperPath, + settings, }: { inputPaths: string[]; vyperPath: string; + settings?: VyperSettings; }): Promise => { const compiler = new Compiler(vyperPath); - const { version, ...contracts } = await compiler.compile(inputPaths); + const { version, ...contracts } = await compiler.compile( + inputPaths, + settings + ); return { version, @@ -249,14 +254,26 @@ subtask(TASK_COMPILE_VYPER) ({ version }) => version ); + const versionsToSettings = Object.fromEntries( + config.vyper.compilers.map(({ version, settings }) => [ + version, + settings, + ]) + ); + const versionGroups: Record = {}; const unmatchedFiles: ResolvedFile[] = []; for (const file of resolvedFiles) { + const settings = versionsToSettings[file.content.versionPragma]; + const hasChanged = vyperFilesCache.hasFileChanged( file.absolutePath, file.contentHash, - { version: file.content.versionPragma } + { + version: file.content.versionPragma, + ...(settings !== undefined ? { settings } : {}), + } ); if (!hasChanged) continue; @@ -266,8 +283,7 @@ subtask(TASK_COMPILE_VYPER) file.content.versionPragma ); - // check if there are files that don't match any configured compiler - // version + // check if there are files that don't match any configured compiler version if (maxSatisfyingVersion === null) { unmatchedFiles.push(file); continue; @@ -298,6 +314,8 @@ ${list}` } for (const [vyperVersion, files] of Object.entries(versionGroups)) { + const settings = versionsToSettings[vyperVersion]; + const vyperBuild: VyperBuild = await run(TASK_COMPILE_VYPER_GET_BUILD, { quiet, vyperVersion, @@ -312,6 +330,7 @@ ${list}` { inputPaths: files.map(({ absolutePath }) => absolutePath), vyperPath: vyperBuild.compilerPath, + settings, } ); @@ -329,7 +348,10 @@ ${list}` lastModificationDate: file.lastModificationDate.valueOf(), contentHash: file.contentHash, sourceName: file.sourceName, - vyperConfig: { version }, + vyperConfig: { + version, + ...(settings !== undefined ? { settings } : {}), + }, versionPragma: file.content.versionPragma, artifacts: [artifact.contractName], }); diff --git a/packages/hardhat-vyper/src/types.ts b/packages/hardhat-vyper/src/types.ts index 8a17cd4c16..bac311129e 100644 --- a/packages/hardhat-vyper/src/types.ts +++ b/packages/hardhat-vyper/src/types.ts @@ -1,7 +1,13 @@ export type VyperUserConfig = string | VyperConfig | MultiVyperConfig; +export interface VyperSettings { + evmVersion: string; + optimize: "gas" | "codesize" | "none"; +} + export interface VyperConfig { version: string; + settings?: VyperSettings; } export interface MultiVyperConfig { diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings-failure/contracts/A.vy b/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings-failure/contracts/A.vy new file mode 100644 index 0000000000..748ebc927a --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings-failure/contracts/A.vy @@ -0,0 +1,5 @@ +# @version 0.3.9 + +@external +def test() -> int128: + return 42 diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings-failure/hardhat.config.js b/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings-failure/hardhat.config.js new file mode 100644 index 0000000000..4574f23059 --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings-failure/hardhat.config.js @@ -0,0 +1,15 @@ +require("../../../src/index"); + +module.exports = { + vyper: { + compilers: [ + { + version: "0.3.9", + settings: { + evmVersion: "paris", + optimize: "gas", + }, + }, + ], + }, +}; diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings/contracts/A.vy b/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings/contracts/A.vy new file mode 100644 index 0000000000..25f7f170c6 --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings/contracts/A.vy @@ -0,0 +1,5 @@ +# @version 0.3.8 + +@external +def test() -> int128: + return 42 diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings/contracts/B.vy b/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings/contracts/B.vy new file mode 100644 index 0000000000..2f6a0a54db --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings/contracts/B.vy @@ -0,0 +1,5 @@ +# @version 0.3.10 + +@external +def test() -> int128: + return 42 diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings/hardhat.config.js b/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings/hardhat.config.js new file mode 100644 index 0000000000..620d5eb0a2 --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings/hardhat.config.js @@ -0,0 +1,21 @@ +require("../../../src/index"); + +module.exports = { + vyper: { + compilers: [ + { + version: "0.3.10", + settings: { + evmVersion: "paris", + optimize: "gas", + }, + }, + { + version: "0.3.8", + settings: { + evmVersion: "shanghai", + }, + }, + ], + }, +}; diff --git a/packages/hardhat-vyper/test/tests.ts b/packages/hardhat-vyper/test/tests.ts index 04ac58d9ea..e445cc89dd 100644 --- a/packages/hardhat-vyper/test/tests.ts +++ b/packages/hardhat-vyper/test/tests.ts @@ -5,6 +5,7 @@ import path from "path"; import { TASK_COMPILE } from "hardhat/builtin-tasks/task-names"; +import fs from "node:fs"; import { VYPER_FILES_CACHE_FILENAME } from "../src/constants"; import { useEnvironment, @@ -44,6 +45,86 @@ describe("Vyper plugin", function () { }); }); + describe("vyper settings", function () { + describe("compilation with different settings", function () { + useFixtureProject("compilation-with-vyper-settings"); + useEnvironment(); + + it("should compile and emit artifacts", async function () { + await this.env.run(TASK_COMPILE); + + assertFileExists(path.join("artifacts", "contracts", "A.vy", "A.json")); + assertFileExists(path.join("artifacts", "contracts", "B.vy", "B.json")); + }); + }); + + describe("compilation with wrong settings", function () { + useFixtureProject("compilation-with-vyper-settings-failure"); + useEnvironment(); + + it("should fail the compilation, invalid settings", async function () { + // compiler version is set to 0.3.9, which does not support the setting 'optimize' + await expect(this.env.run(TASK_COMPILE)).to.be.rejectedWith( + Error, + /unrecognized arguments: --optimize/ + ); + }); + }); + }); + + describe("caching mechanism", function () { + describe("caching mechanism without vyper settings", function () { + useFixtureProject("compilation-single-file"); + useEnvironment(); + + it("should not re-compile the contract because of the cache", async function () { + await this.env.run(TASK_COMPILE); + + const stats1 = fs.statSync( + path.join("artifacts", "contracts", "A.vy", "A.json") + ); + + // it should not compile again so the contract should not be modified + await this.env.run(TASK_COMPILE); + + const stats2 = fs.statSync( + path.join("artifacts", "contracts", "A.vy", "A.json") + ); + + assert.equal(stats1.mtimeMs, stats2.mtimeMs); + }); + }); + + describe("caching mechanism with vyper settings", function () { + useFixtureProject("compilation-with-vyper-settings"); + useEnvironment(); + + it("should not re-compile the contract because of the cache", async function () { + await this.env.run(TASK_COMPILE); + + const stats1A = fs.statSync( + path.join("artifacts", "contracts", "A.vy", "A.json") + ); + const stats1B = fs.statSync( + path.join("artifacts", "contracts", "B.vy", "B.json") + ); + + // it should not compile again so the contracts should not be modified + await this.env.run(TASK_COMPILE); + + const stats2A = fs.statSync( + path.join("artifacts", "contracts", "A.vy", "A.json") + ); + const stats2B = fs.statSync( + path.join("artifacts", "contracts", "B.vy", "B.json") + ); + + assert.equal(stats1A.mtimeMs, stats2A.mtimeMs); + assert.equal(stats1B.mtimeMs, stats2B.mtimeMs); + }); + }); + }); + describe("old versions of vyper", function () { useFixtureProject("old-vyper-versions"); From e09dfad17fca069ed3418dd9c13c8d8621cd4fbc Mon Sep 17 00:00:00 2001 From: Christopher Dedominici <18092467+ChristopherDedominici@users.noreply.github.com> Date: Wed, 14 Feb 2024 23:47:45 +0100 Subject: [PATCH 02/12] fix readme --- packages/hardhat-vyper/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/hardhat-vyper/README.md b/packages/hardhat-vyper/README.md index db5813b8e1..5bb25cc7d5 100644 --- a/packages/hardhat-vyper/README.md +++ b/packages/hardhat-vyper/README.md @@ -58,7 +58,7 @@ module.exports = { }; ``` -You can also configure multiple versions of the Vyper compiler together with the compiler settings properties evmVersion (supported starting from Vyper 0.3.8) and optimize (supported starting from Vyper 0.3.10). +You can also configure multiple versions of the Vyper compiler, as well as the compiler settings evmVersion (available from Vyper 0.3.8) and optimize (available from Vyper 0.3.10) ```js module.exports = { From bb9a4023dcdf69ff1854841f24829d05e3f696c5 Mon Sep 17 00:00:00 2001 From: Christopher Dedominici <18092467+ChristopherDedominici@users.noreply.github.com> Date: Thu, 15 Feb 2024 17:57:14 +0100 Subject: [PATCH 03/12] Create fluffy-cups-clap.md --- .changeset/fluffy-cups-clap.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/fluffy-cups-clap.md diff --git a/.changeset/fluffy-cups-clap.md b/.changeset/fluffy-cups-clap.md new file mode 100644 index 0000000000..5e35281612 --- /dev/null +++ b/.changeset/fluffy-cups-clap.md @@ -0,0 +1,5 @@ +--- +"@nomiclabs/hardhat-vyper": patch +--- + +Added support for vyper settings 'evmVersion' and 'optimize' From 0bbfd007dad0294f50d88c0568777798506b396c Mon Sep 17 00:00:00 2001 From: Christopher Dedominici <18092467+ChristopherDedominici@users.noreply.github.com> Date: Wed, 14 Feb 2024 23:56:11 +0100 Subject: [PATCH 04/12] fix test --- .../compilation-with-vyper-settings-failure/contracts/A.vy | 2 +- .../compilation-with-vyper-settings-failure/hardhat.config.js | 2 +- packages/hardhat-vyper/test/tests.ts | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings-failure/contracts/A.vy b/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings-failure/contracts/A.vy index 748ebc927a..33209704f2 100644 --- a/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings-failure/contracts/A.vy +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings-failure/contracts/A.vy @@ -1,4 +1,4 @@ -# @version 0.3.9 +# @version 0.3.7 @external def test() -> int128: diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings-failure/hardhat.config.js b/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings-failure/hardhat.config.js index 4574f23059..d4d7b78b4c 100644 --- a/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings-failure/hardhat.config.js +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings-failure/hardhat.config.js @@ -4,7 +4,7 @@ module.exports = { vyper: { compilers: [ { - version: "0.3.9", + version: "0.3.7", settings: { evmVersion: "paris", optimize: "gas", diff --git a/packages/hardhat-vyper/test/tests.ts b/packages/hardhat-vyper/test/tests.ts index e445cc89dd..ce93a6402c 100644 --- a/packages/hardhat-vyper/test/tests.ts +++ b/packages/hardhat-vyper/test/tests.ts @@ -63,10 +63,10 @@ describe("Vyper plugin", function () { useEnvironment(); it("should fail the compilation, invalid settings", async function () { - // compiler version is set to 0.3.9, which does not support the setting 'optimize' + // compiler version is set to 0.3.7, which does not support the settings 'evmVersion' and 'optimize' await expect(this.env.run(TASK_COMPILE)).to.be.rejectedWith( Error, - /unrecognized arguments: --optimize/ + /--evm-version paris --optimize gas/ ); }); }); From 5f078bc4d4bdd6f21a8662e1f0c8fa4461a2f038 Mon Sep 17 00:00:00 2001 From: Christopher Dedominici <18092467+ChristopherDedominici@users.noreply.github.com> Date: Thu, 15 Feb 2024 00:15:48 +0100 Subject: [PATCH 05/12] fix VyperSettings type --- packages/hardhat-vyper/src/compiler.ts | 6 +++--- packages/hardhat-vyper/src/index.ts | 8 +++----- packages/hardhat-vyper/src/types.ts | 4 ++-- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/packages/hardhat-vyper/src/compiler.ts b/packages/hardhat-vyper/src/compiler.ts index 7242e660ba..c4f8e837ff 100644 --- a/packages/hardhat-vyper/src/compiler.ts +++ b/packages/hardhat-vyper/src/compiler.ts @@ -8,14 +8,14 @@ export class Compiler { * * @param inputPaths array of paths to contracts to be compiled */ - public async compile(inputPaths: string[], settings?: VyperSettings) { + public async compile(inputPaths: string[], settings: VyperSettings = {}) { const output: string = await new Promise((resolve, reject) => { let settingsStr = - settings?.evmVersion !== undefined + settings.evmVersion !== undefined ? `--evm-version ${settings.evmVersion} ` : ""; settingsStr += - settings?.optimize !== undefined + settings.optimize !== undefined ? `--optimize ${String(settings.optimize)} ` : ""; diff --git a/packages/hardhat-vyper/src/index.ts b/packages/hardhat-vyper/src/index.ts index a3cd024570..52b294d3d3 100644 --- a/packages/hardhat-vyper/src/index.ts +++ b/packages/hardhat-vyper/src/index.ts @@ -265,14 +265,12 @@ subtask(TASK_COMPILE_VYPER) const unmatchedFiles: ResolvedFile[] = []; for (const file of resolvedFiles) { - const settings = versionsToSettings[file.content.versionPragma]; - const hasChanged = vyperFilesCache.hasFileChanged( file.absolutePath, file.contentHash, { version: file.content.versionPragma, - ...(settings !== undefined ? { settings } : {}), + settings: versionsToSettings[file.content.versionPragma] ?? {}, } ); @@ -314,7 +312,7 @@ ${list}` } for (const [vyperVersion, files] of Object.entries(versionGroups)) { - const settings = versionsToSettings[vyperVersion]; + const settings = versionsToSettings[vyperVersion] ?? {}; const vyperBuild: VyperBuild = await run(TASK_COMPILE_VYPER_GET_BUILD, { quiet, @@ -350,7 +348,7 @@ ${list}` sourceName: file.sourceName, vyperConfig: { version, - ...(settings !== undefined ? { settings } : {}), + settings, }, versionPragma: file.content.versionPragma, artifacts: [artifact.contractName], diff --git a/packages/hardhat-vyper/src/types.ts b/packages/hardhat-vyper/src/types.ts index bac311129e..833327e240 100644 --- a/packages/hardhat-vyper/src/types.ts +++ b/packages/hardhat-vyper/src/types.ts @@ -1,8 +1,8 @@ export type VyperUserConfig = string | VyperConfig | MultiVyperConfig; export interface VyperSettings { - evmVersion: string; - optimize: "gas" | "codesize" | "none"; + evmVersion?: string; + optimize?: "gas" | "codesize" | "none"; } export interface VyperConfig { From e7ddc3efcd7a4f64e1f7ee8c9b0c66ce78a125ef Mon Sep 17 00:00:00 2001 From: Christopher Dedominici <18092467+ChristopherDedominici@users.noreply.github.com> Date: Sun, 18 Feb 2024 21:13:36 +0100 Subject: [PATCH 06/12] improve handling of optimize setting --- packages/hardhat-vyper/README.md | 2 +- packages/hardhat-vyper/src/compiler.ts | 81 ++++++++++++++--- packages/hardhat-vyper/src/index.ts | 46 ++++++---- packages/hardhat-vyper/src/types.ts | 2 +- .../test/fixture-projects/.gitignore | 4 +- .../optimize-invalid-type}/contracts/A.vy | 2 +- .../optimize-invalid-type}/hardhat.config.js | 6 +- .../contracts/A.vy | 5 ++ .../hardhat.config.js | 15 ++++ .../contracts/A.vy | 5 ++ .../hardhat.config.js | 15 ++++ .../optimize-set-to-true/contracts/A.vy | 5 ++ .../optimize-set-to-true/hardhat.config.js | 15 ++++ .../contracts/A.vy | 5 ++ .../hardhat.config.js | 15 ++++ .../contracts/A.vy | 5 ++ .../hardhat.config.js | 15 ++++ .../contracts/A.vy | 5 ++ .../hardhat.config.js | 15 ++++ packages/hardhat-vyper/test/tests.ts | 89 +++++++++++++++++-- 20 files changed, 312 insertions(+), 40 deletions(-) rename packages/hardhat-vyper/test/fixture-projects/{compilation-with-vyper-settings-failure => compilation-with-settings-option-variants/optimize-invalid-type}/contracts/A.vy (72%) rename packages/hardhat-vyper/test/fixture-projects/{compilation-with-vyper-settings-failure => compilation-with-settings-option-variants/optimize-invalid-type}/hardhat.config.js (62%) create mode 100644 packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-always-available-new-versions/contracts/A.vy create mode 100644 packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-always-available-new-versions/hardhat.config.js create mode 100644 packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-always-available-old-versions/contracts/A.vy create mode 100644 packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-always-available-old-versions/hardhat.config.js create mode 100644 packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-true/contracts/A.vy create mode 100644 packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-true/hardhat.config.js create mode 100644 packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-string-not-available-old-versions/contracts/A.vy create mode 100644 packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-string-not-available-old-versions/hardhat.config.js create mode 100644 packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-true-not-available-new-versions/contracts/A.vy create mode 100644 packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-true-not-available-new-versions/hardhat.config.js create mode 100644 packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-true-not-available-old-versions/contracts/A.vy create mode 100644 packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-true-not-available-old-versions/hardhat.config.js diff --git a/packages/hardhat-vyper/README.md b/packages/hardhat-vyper/README.md index 5bb25cc7d5..dd421b6742 100644 --- a/packages/hardhat-vyper/README.md +++ b/packages/hardhat-vyper/README.md @@ -58,7 +58,7 @@ module.exports = { }; ``` -You can also configure multiple versions of the Vyper compiler, as well as the compiler settings evmVersion (available from Vyper 0.3.8) and optimize (available from Vyper 0.3.10) +You can also configure multiple versions of the Vyper compiler, as well as the compiler settings evmVersion and optimize. See the [Vyper docs](https://docs.vyperlang.org/en/v0.3.10/compiling-a-contract.html) for more info. ```js module.exports = { diff --git a/packages/hardhat-vyper/src/compiler.ts b/packages/hardhat-vyper/src/compiler.ts index c4f8e837ff..c11d8f4704 100644 --- a/packages/hardhat-vyper/src/compiler.ts +++ b/packages/hardhat-vyper/src/compiler.ts @@ -1,4 +1,5 @@ import { exec } from "child_process"; +import semver from "semver"; import { VyperSettings } from "./types"; export class Compiler { @@ -8,19 +9,16 @@ export class Compiler { * * @param inputPaths array of paths to contracts to be compiled */ - public async compile(inputPaths: string[], settings: VyperSettings = {}) { + public async compile( + inputPaths: string[], + compilerVersion: string = "", + settings: VyperSettings = {} + ) { const output: string = await new Promise((resolve, reject) => { - let settingsStr = - settings.evmVersion !== undefined - ? `--evm-version ${settings.evmVersion} ` - : ""; - settingsStr += - settings.optimize !== undefined - ? `--optimize ${String(settings.optimize)} ` - : ""; + const settingsCmd = getSettingsCmd(compilerVersion, settings); const process = exec( - `${this._pathToVyper} ${settingsStr} -f combined_json ${inputPaths.join( + `${this._pathToVyper} ${settingsCmd} -f combined_json ${inputPaths.join( " " )}`, { @@ -40,3 +38,66 @@ export class Compiler { return JSON.parse(output); } } + +function getSettingsCmd( + compilerVersion: string, + settings: VyperSettings +): string { + let settingsStr = + settings.evmVersion !== undefined + ? `--evm-version ${settings.evmVersion} ` + : ""; + + settingsStr += getOptimize(compilerVersion, settings.optimize); + + return settingsStr; +} + +function getOptimize( + compilerVersion: string, + optimize: string | boolean | undefined +): string { + if (compilerVersion === "" && optimize !== undefined) { + throw new Error( + "The 'compilerVersion' parameter must be set when the setting 'optimize' is set." + ); + } + + if (optimize === undefined) { + return ""; + } + + if (typeof optimize === "boolean") { + if (optimize) { + if ( + semver.gte(compilerVersion, "0.3.10") || + semver.lt(compilerVersion, "0.3.1") + ) { + throw new Error( + `The 'optimize' setting with value 'true' is not supported for versions of the Vyper compiler older than 0.3.1 or newer than 0.3.10. You are currently using version ${compilerVersion}.` + ); + } + + // The optimizer is enabled by default + return ""; + } else { + return semver.lt(compilerVersion, "0.3.10") + ? "--no-optimize" + : "--optimize none"; + } + } + + if (typeof optimize === "string") { + if (semver.gte(compilerVersion, "0.3.10")) { + return `--optimize ${optimize}`; + } + + throw new Error( + `The 'optimize' setting, when specified as a string value, is available only starting from the Vyper compiler version 0.3.10. You are currently using version ${compilerVersion}.` + ); + } + + throw new Error( + `The 'optimize' setting has an invalid type value. Type is: ${typeof optimize}.` + ); +} diff --git a/packages/hardhat-vyper/src/index.ts b/packages/hardhat-vyper/src/index.ts index 52b294d3d3..e55c129cda 100644 --- a/packages/hardhat-vyper/src/index.ts +++ b/packages/hardhat-vyper/src/index.ts @@ -188,16 +188,19 @@ subtask(TASK_COMPILE_VYPER_RUN_BINARY) async ({ inputPaths, vyperPath, + vyperVersion, settings, }: { inputPaths: string[]; vyperPath: string; + vyperVersion?: string; settings?: VyperSettings; }): Promise => { const compiler = new Compiler(vyperPath); const { version, ...contracts } = await compiler.compile( inputPaths, + vyperVersion, settings ); @@ -261,21 +264,13 @@ subtask(TASK_COMPILE_VYPER) ]) ); - const versionGroups: Record = {}; + const versionGroups: Record< + string, + { files: ResolvedFile[]; settings: VyperSettings } + > = {}; const unmatchedFiles: ResolvedFile[] = []; for (const file of resolvedFiles) { - const hasChanged = vyperFilesCache.hasFileChanged( - file.absolutePath, - file.contentHash, - { - version: file.content.versionPragma, - settings: versionsToSettings[file.content.versionPragma] ?? {}, - } - ); - - if (!hasChanged) continue; - const maxSatisfyingVersion = semver.maxSatisfying( configuredVersions, file.content.versionPragma @@ -287,12 +282,28 @@ subtask(TASK_COMPILE_VYPER) continue; } + const settings = versionsToSettings[maxSatisfyingVersion] ?? {}; + + const hasChanged = vyperFilesCache.hasFileChanged( + file.absolutePath, + file.contentHash, + { + version: maxSatisfyingVersion, + settings, + } + ); + + if (!hasChanged) continue; + if (versionGroups[maxSatisfyingVersion] === undefined) { - versionGroups[maxSatisfyingVersion] = [file]; + versionGroups[maxSatisfyingVersion] = { + files: [file], + settings, + }; continue; } - versionGroups[maxSatisfyingVersion].push(file); + versionGroups[maxSatisfyingVersion].files.push(file); } if (unmatchedFiles.length > 0) { @@ -311,9 +322,9 @@ ${list}` ); } - for (const [vyperVersion, files] of Object.entries(versionGroups)) { - const settings = versionsToSettings[vyperVersion] ?? {}; - + for (const [vyperVersion, { files, settings }] of Object.entries( + versionGroups + )) { const vyperBuild: VyperBuild = await run(TASK_COMPILE_VYPER_GET_BUILD, { quiet, vyperVersion, @@ -328,6 +339,7 @@ ${list}` { inputPaths: files.map(({ absolutePath }) => absolutePath), vyperPath: vyperBuild.compilerPath, + vyperVersion, settings, } ); diff --git a/packages/hardhat-vyper/src/types.ts b/packages/hardhat-vyper/src/types.ts index 833327e240..5eaad0b65d 100644 --- a/packages/hardhat-vyper/src/types.ts +++ b/packages/hardhat-vyper/src/types.ts @@ -2,7 +2,7 @@ export type VyperUserConfig = string | VyperConfig | MultiVyperConfig; export interface VyperSettings { evmVersion?: string; - optimize?: "gas" | "codesize" | "none"; + optimize?: string | boolean; } export interface VyperConfig { diff --git a/packages/hardhat-vyper/test/fixture-projects/.gitignore b/packages/hardhat-vyper/test/fixture-projects/.gitignore index 1a65e437ab..64036ac854 100644 --- a/packages/hardhat-vyper/test/fixture-projects/.gitignore +++ b/packages/hardhat-vyper/test/fixture-projects/.gitignore @@ -1,2 +1,2 @@ -/*/cache -/*/artifacts +/**/cache +/**/artifacts diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings-failure/contracts/A.vy b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-invalid-type/contracts/A.vy similarity index 72% rename from packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings-failure/contracts/A.vy rename to packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-invalid-type/contracts/A.vy index 33209704f2..748ebc927a 100644 --- a/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings-failure/contracts/A.vy +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-invalid-type/contracts/A.vy @@ -1,4 +1,4 @@ -# @version 0.3.7 +# @version 0.3.9 @external def test() -> int128: diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings-failure/hardhat.config.js b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-invalid-type/hardhat.config.js similarity index 62% rename from packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings-failure/hardhat.config.js rename to packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-invalid-type/hardhat.config.js index d4d7b78b4c..e031582d90 100644 --- a/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings-failure/hardhat.config.js +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-invalid-type/hardhat.config.js @@ -1,13 +1,13 @@ -require("../../../src/index"); +require("../../../../src/index"); module.exports = { vyper: { compilers: [ { - version: "0.3.7", + version: "0.3.9", settings: { evmVersion: "paris", - optimize: "gas", + optimize: 12, }, }, ], diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-always-available-new-versions/contracts/A.vy b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-always-available-new-versions/contracts/A.vy new file mode 100644 index 0000000000..2f6a0a54db --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-always-available-new-versions/contracts/A.vy @@ -0,0 +1,5 @@ +# @version 0.3.10 + +@external +def test() -> int128: + return 42 diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-always-available-new-versions/hardhat.config.js b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-always-available-new-versions/hardhat.config.js new file mode 100644 index 0000000000..e59e652644 --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-always-available-new-versions/hardhat.config.js @@ -0,0 +1,15 @@ +require("../../../../src/index"); + +module.exports = { + vyper: { + compilers: [ + { + version: "0.3.10", + settings: { + evmVersion: "paris", + optimize: false, + }, + }, + ], + }, +}; diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-always-available-old-versions/contracts/A.vy b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-always-available-old-versions/contracts/A.vy new file mode 100644 index 0000000000..748ebc927a --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-always-available-old-versions/contracts/A.vy @@ -0,0 +1,5 @@ +# @version 0.3.9 + +@external +def test() -> int128: + return 42 diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-always-available-old-versions/hardhat.config.js b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-always-available-old-versions/hardhat.config.js new file mode 100644 index 0000000000..a1f69ac41c --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-always-available-old-versions/hardhat.config.js @@ -0,0 +1,15 @@ +require("../../../../src/index"); + +module.exports = { + vyper: { + compilers: [ + { + version: "0.3.9", + settings: { + evmVersion: "paris", + optimize: false, + }, + }, + ], + }, +}; diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-true/contracts/A.vy b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-true/contracts/A.vy new file mode 100644 index 0000000000..748ebc927a --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-true/contracts/A.vy @@ -0,0 +1,5 @@ +# @version 0.3.9 + +@external +def test() -> int128: + return 42 diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-true/hardhat.config.js b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-true/hardhat.config.js new file mode 100644 index 0000000000..965f42bb5a --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-true/hardhat.config.js @@ -0,0 +1,15 @@ +require("../../../../src/index"); + +module.exports = { + vyper: { + compilers: [ + { + version: "0.3.9", + settings: { + evmVersion: "paris", + optimize: true, + }, + }, + ], + }, +}; diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-string-not-available-old-versions/contracts/A.vy b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-string-not-available-old-versions/contracts/A.vy new file mode 100644 index 0000000000..748ebc927a --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-string-not-available-old-versions/contracts/A.vy @@ -0,0 +1,5 @@ +# @version 0.3.9 + +@external +def test() -> int128: + return 42 diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-string-not-available-old-versions/hardhat.config.js b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-string-not-available-old-versions/hardhat.config.js new file mode 100644 index 0000000000..a9eb741f4d --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-string-not-available-old-versions/hardhat.config.js @@ -0,0 +1,15 @@ +require("../../../../src/index"); + +module.exports = { + vyper: { + compilers: [ + { + version: "0.3.9", + settings: { + evmVersion: "paris", + optimize: "true", + }, + }, + ], + }, +}; diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-true-not-available-new-versions/contracts/A.vy b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-true-not-available-new-versions/contracts/A.vy new file mode 100644 index 0000000000..2f6a0a54db --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-true-not-available-new-versions/contracts/A.vy @@ -0,0 +1,5 @@ +# @version 0.3.10 + +@external +def test() -> int128: + return 42 diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-true-not-available-new-versions/hardhat.config.js b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-true-not-available-new-versions/hardhat.config.js new file mode 100644 index 0000000000..de9ea2595a --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-true-not-available-new-versions/hardhat.config.js @@ -0,0 +1,15 @@ +require("../../../../src/index"); + +module.exports = { + vyper: { + compilers: [ + { + version: "0.3.10", + settings: { + evmVersion: "paris", + optimize: true, + }, + }, + ], + }, +}; diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-true-not-available-old-versions/contracts/A.vy b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-true-not-available-old-versions/contracts/A.vy new file mode 100644 index 0000000000..14de3134ac --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-true-not-available-old-versions/contracts/A.vy @@ -0,0 +1,5 @@ +# @version 0.3.0 + +@external +def test() -> int128: + return 42 diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-true-not-available-old-versions/hardhat.config.js b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-true-not-available-old-versions/hardhat.config.js new file mode 100644 index 0000000000..1fa88e8c40 --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-true-not-available-old-versions/hardhat.config.js @@ -0,0 +1,15 @@ +require("../../../../src/index"); + +module.exports = { + vyper: { + compilers: [ + { + version: "0.3.0", + settings: { + evmVersion: "paris", + optimize: true, + }, + }, + ], + }, +}; diff --git a/packages/hardhat-vyper/test/tests.ts b/packages/hardhat-vyper/test/tests.ts index ce93a6402c..4350f916cf 100644 --- a/packages/hardhat-vyper/test/tests.ts +++ b/packages/hardhat-vyper/test/tests.ts @@ -58,15 +58,94 @@ describe("Vyper plugin", function () { }); }); - describe("compilation with wrong settings", function () { - useFixtureProject("compilation-with-vyper-settings-failure"); + describe("optimize, as boolean type, can always be set to false in versions >= 0.3.10 (flag --optimize none)", function () { + useFixtureProject( + "compilation-with-settings-option-variants/optimize-set-to-false-always-available-new-versions" + ); + useEnvironment(); + + it("should compile successfully", async function () { + await this.env.run(TASK_COMPILE); + assertFileExists(path.join("artifacts", "contracts", "A.vy", "A.json")); + }); + }); + + describe("optimize, as boolean type, can always be set to false in versions < 0.3.10 (flag --no-optimize)", function () { + useFixtureProject( + "compilation-with-settings-option-variants/optimize-set-to-false-always-available-old-versions" + ); + useEnvironment(); + + it("should compile successfully", async function () { + await this.env.run(TASK_COMPILE); + assertFileExists(path.join("artifacts", "contracts", "A.vy", "A.json")); + }); + }); + + describe("optimize setting set to true in supported versions", function () { + useFixtureProject( + "compilation-with-settings-option-variants/optimize-set-to-true" + ); + useEnvironment(); + + it("should compile successfully", async function () { + await this.env.run(TASK_COMPILE); + assertFileExists(path.join("artifacts", "contracts", "A.vy", "A.json")); + }); + }); + + describe("optimize set to true is not available for versions >= 0.3.10", function () { + useFixtureProject( + "compilation-with-settings-option-variants/optimize-true-not-available-new-versions" + ); + useEnvironment(); + + it("should fail the compilation", async function () { + await expect(this.env.run(TASK_COMPILE)).to.be.rejectedWith( + Error, + "The 'optimize' setting with value 'true' is not supported for versions of the Vyper compiler older than 0.3.1 or newer than 0.3.10. You are currently using version 0.3.10." + ); + }); + }); + + describe("optimize set to true is not available for versions < 0.3.1", function () { + useFixtureProject( + "compilation-with-settings-option-variants/optimize-true-not-available-old-versions" + ); + useEnvironment(); + + it("should fail the compilation", async function () { + await expect(this.env.run(TASK_COMPILE)).to.be.rejectedWith( + Error, + "The 'optimize' setting with value 'true' is not supported for versions of the Vyper compiler older than 0.3.1 or newer than 0.3.10. You are currently using version 0.3.0." + ); + }); + }); + + describe("optimize setting cannot be a string for version < 0.3.10", function () { + useFixtureProject( + "compilation-with-settings-option-variants/optimize-string-not-available-old-versions" + ); + useEnvironment(); + + it("should fail the compilation", async function () { + await expect(this.env.run(TASK_COMPILE)).to.be.rejectedWith( + Error, + "The 'optimize' setting, when specified as a string value, is available only starting from the Vyper compiler version 0.3.10. You are currently using version 0.3.9." + ); + }); + }); + + describe("optimize setting must be a string or boolean type", function () { + useFixtureProject( + "compilation-with-settings-option-variants/optimize-invalid-type" + ); useEnvironment(); - it("should fail the compilation, invalid settings", async function () { - // compiler version is set to 0.3.7, which does not support the settings 'evmVersion' and 'optimize' + it("should fail the compilation", async function () { await expect(this.env.run(TASK_COMPILE)).to.be.rejectedWith( Error, - /--evm-version paris --optimize gas/ + "The 'optimize' setting has an invalid type value. Type is: number." ); }); }); From da8b0ec26c726ee7eb02b05d5240082ecc2bfe46 Mon Sep 17 00:00:00 2001 From: Franco Victorio Date: Tue, 2 Apr 2024 11:25:17 +0200 Subject: [PATCH 07/12] Use VyperPluginError instead of Error --- packages/hardhat-vyper/src/compiler.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/hardhat-vyper/src/compiler.ts b/packages/hardhat-vyper/src/compiler.ts index c11d8f4704..34547b7a01 100644 --- a/packages/hardhat-vyper/src/compiler.ts +++ b/packages/hardhat-vyper/src/compiler.ts @@ -1,6 +1,7 @@ import { exec } from "child_process"; import semver from "semver"; import { VyperSettings } from "./types"; +import { VyperPluginError } from "./util"; export class Compiler { constructor(private _pathToVyper: string) {} @@ -58,7 +59,7 @@ function getOptimize( optimize: string | boolean | undefined ): string { if (compilerVersion === "" && optimize !== undefined) { - throw new Error( + throw new VyperPluginError( "The 'compilerVersion' parameter must be set when the setting 'optimize' is set." ); } @@ -73,7 +74,7 @@ function getOptimize( semver.gte(compilerVersion, "0.3.10") || semver.lt(compilerVersion, "0.3.1") ) { - throw new Error( + throw new VyperPluginError( `The 'optimize' setting with value 'true' is not supported for versions of the Vyper compiler older than 0.3.1 or newer than 0.3.10. You are currently using version ${compilerVersion}.` ); } @@ -92,12 +93,12 @@ function getOptimize( return `--optimize ${optimize}`; } - throw new Error( + throw new VyperPluginError( `The 'optimize' setting, when specified as a string value, is available only starting from the Vyper compiler version 0.3.10. You are currently using version ${compilerVersion}.` ); } - throw new Error( + throw new VyperPluginError( `The 'optimize' setting has an invalid type value. Type is: ${typeof optimize}.` ); } From 87e2516a2c58e800d2eb7d8aa1c46a4dcc00b9b7 Mon Sep 17 00:00:00 2001 From: Christopher Dedominici <18092467+ChristopherDedominici@users.noreply.github.com> Date: Tue, 2 Apr 2024 21:16:09 +0200 Subject: [PATCH 08/12] fix optimize flag for versions < 0.3.1 --- packages/hardhat-vyper/src/compiler.ts | 6 ++++++ .../contracts/A.vy | 5 +++++ .../hardhat.config.js | 15 +++++++++++++++ packages/hardhat-vyper/test/tests.ts | 16 +++++++++++++++- 4 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-not-available-old-versions/contracts/A.vy create mode 100644 packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-not-available-old-versions/hardhat.config.js diff --git a/packages/hardhat-vyper/src/compiler.ts b/packages/hardhat-vyper/src/compiler.ts index 34547b7a01..bfb2283d96 100644 --- a/packages/hardhat-vyper/src/compiler.ts +++ b/packages/hardhat-vyper/src/compiler.ts @@ -82,6 +82,12 @@ function getOptimize( // The optimizer is enabled by default return ""; } else { + if (semver.lt(compilerVersion, "0.3.1")) { + throw new VyperPluginError( + `The 'optimize' setting with value 'false' is not supported for versions of the Vyper compiler older than 0.3.1. You are currently using version ${compilerVersion}.` + ); + } + return semver.lt(compilerVersion, "0.3.10") ? "--no-optimize" : "--optimize none"; diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-not-available-old-versions/contracts/A.vy b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-not-available-old-versions/contracts/A.vy new file mode 100644 index 0000000000..14de3134ac --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-not-available-old-versions/contracts/A.vy @@ -0,0 +1,5 @@ +# @version 0.3.0 + +@external +def test() -> int128: + return 42 diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-not-available-old-versions/hardhat.config.js b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-not-available-old-versions/hardhat.config.js new file mode 100644 index 0000000000..4527da42e7 --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-not-available-old-versions/hardhat.config.js @@ -0,0 +1,15 @@ +require("../../../../src/index"); + +module.exports = { + vyper: { + compilers: [ + { + version: "0.3.0", + settings: { + evmVersion: "istanbul", + optimize: false, + }, + }, + ], + }, +}; diff --git a/packages/hardhat-vyper/test/tests.ts b/packages/hardhat-vyper/test/tests.ts index 4350f916cf..7010eedd26 100644 --- a/packages/hardhat-vyper/test/tests.ts +++ b/packages/hardhat-vyper/test/tests.ts @@ -70,7 +70,7 @@ describe("Vyper plugin", function () { }); }); - describe("optimize, as boolean type, can always be set to false in versions < 0.3.10 (flag --no-optimize)", function () { + describe("optimize, as boolean type, can always be set to false in versions 0.3.0 < v < 0.3.10 (flag --no-optimize)", function () { useFixtureProject( "compilation-with-settings-option-variants/optimize-set-to-false-always-available-old-versions" ); @@ -82,6 +82,20 @@ describe("Vyper plugin", function () { }); }); + describe("optimize, as boolean type, cannot be set to false in versions < 0.3.1", function () { + useFixtureProject( + "compilation-with-settings-option-variants/optimize-set-to-false-not-available-old-versions" + ); + useEnvironment(); + + it("should compile successfully", async function () { + await expect(this.env.run(TASK_COMPILE)).to.be.rejectedWith( + Error, + "The 'optimize' setting with value 'false' is not supported for versions of the Vyper compiler older than 0.3.1. You are currently using version 0.3.0." + ); + }); + }); + describe("optimize setting set to true in supported versions", function () { useFixtureProject( "compilation-with-settings-option-variants/optimize-set-to-true" From d466a56dbed95d0d84efd526940217ac2c88d55d Mon Sep 17 00:00:00 2001 From: Christopher Dedominici <18092467+ChristopherDedominici@users.noreply.github.com> Date: Fri, 5 Apr 2024 15:52:49 +0200 Subject: [PATCH 09/12] small PR's comments fixes --- packages/hardhat-vyper/src/compiler.ts | 8 ++++---- .../contracts/A.vy | 0 .../hardhat.config.js | 0 packages/hardhat-vyper/test/tests.ts | 14 +++++++------- 4 files changed, 11 insertions(+), 11 deletions(-) rename packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/{optimize-set-to-false-always-available-old-versions => optimize-set-to-false-always-available-old-versions-after-0.3.0}/contracts/A.vy (100%) rename packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/{optimize-set-to-false-always-available-old-versions => optimize-set-to-false-always-available-old-versions-after-0.3.0}/hardhat.config.js (100%) diff --git a/packages/hardhat-vyper/src/compiler.ts b/packages/hardhat-vyper/src/compiler.ts index bfb2283d96..134ea72bda 100644 --- a/packages/hardhat-vyper/src/compiler.ts +++ b/packages/hardhat-vyper/src/compiler.ts @@ -72,19 +72,19 @@ function getOptimize( if (optimize) { if ( semver.gte(compilerVersion, "0.3.10") || - semver.lt(compilerVersion, "0.3.1") + semver.lte(compilerVersion, "0.3.0") ) { throw new VyperPluginError( - `The 'optimize' setting with value 'true' is not supported for versions of the Vyper compiler older than 0.3.1 or newer than 0.3.10. You are currently using version ${compilerVersion}.` + `The 'optimize' setting with value 'true' is not supported for versions of the Vyper compiler older than or equal to 0.3.0 or newer than or equal to 0.3.10. You are currently using version ${compilerVersion}.` ); } // The optimizer is enabled by default return ""; } else { - if (semver.lt(compilerVersion, "0.3.1")) { + if (semver.lte(compilerVersion, "0.3.0")) { throw new VyperPluginError( - `The 'optimize' setting with value 'false' is not supported for versions of the Vyper compiler older than 0.3.1. You are currently using version ${compilerVersion}.` + `The 'optimize' setting with value 'false' is not supported for versions of the Vyper compiler older than or equal to 0.3.0. You are currently using version ${compilerVersion}.` ); } diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-always-available-old-versions/contracts/A.vy b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-always-available-old-versions-after-0.3.0/contracts/A.vy similarity index 100% rename from packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-always-available-old-versions/contracts/A.vy rename to packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-always-available-old-versions-after-0.3.0/contracts/A.vy diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-always-available-old-versions/hardhat.config.js b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-always-available-old-versions-after-0.3.0/hardhat.config.js similarity index 100% rename from packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-always-available-old-versions/hardhat.config.js rename to packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-always-available-old-versions-after-0.3.0/hardhat.config.js diff --git a/packages/hardhat-vyper/test/tests.ts b/packages/hardhat-vyper/test/tests.ts index 7010eedd26..721b16dae5 100644 --- a/packages/hardhat-vyper/test/tests.ts +++ b/packages/hardhat-vyper/test/tests.ts @@ -72,7 +72,7 @@ describe("Vyper plugin", function () { describe("optimize, as boolean type, can always be set to false in versions 0.3.0 < v < 0.3.10 (flag --no-optimize)", function () { useFixtureProject( - "compilation-with-settings-option-variants/optimize-set-to-false-always-available-old-versions" + "compilation-with-settings-option-variants/optimize-set-to-false-always-available-old-versions-after-0.3.0" ); useEnvironment(); @@ -82,16 +82,16 @@ describe("Vyper plugin", function () { }); }); - describe("optimize, as boolean type, cannot be set to false in versions < 0.3.1", function () { + describe("optimize, as boolean type, cannot be set to false in versions <= 0.3.0", function () { useFixtureProject( "compilation-with-settings-option-variants/optimize-set-to-false-not-available-old-versions" ); useEnvironment(); - it("should compile successfully", async function () { + it("should fail the compilation", async function () { await expect(this.env.run(TASK_COMPILE)).to.be.rejectedWith( Error, - "The 'optimize' setting with value 'false' is not supported for versions of the Vyper compiler older than 0.3.1. You are currently using version 0.3.0." + "The 'optimize' setting with value 'false' is not supported for versions of the Vyper compiler older than or equal to 0.3.0. You are currently using version 0.3.0." ); }); }); @@ -117,12 +117,12 @@ describe("Vyper plugin", function () { it("should fail the compilation", async function () { await expect(this.env.run(TASK_COMPILE)).to.be.rejectedWith( Error, - "The 'optimize' setting with value 'true' is not supported for versions of the Vyper compiler older than 0.3.1 or newer than 0.3.10. You are currently using version 0.3.10." + "The 'optimize' setting with value 'true' is not supported for versions of the Vyper compiler older than or equal to 0.3.0 or newer than or equal to 0.3.10. You are currently using version 0.3.10." ); }); }); - describe("optimize set to true is not available for versions < 0.3.1", function () { + describe("optimize set to true is not available for versions <= 0.3.0", function () { useFixtureProject( "compilation-with-settings-option-variants/optimize-true-not-available-old-versions" ); @@ -131,7 +131,7 @@ describe("Vyper plugin", function () { it("should fail the compilation", async function () { await expect(this.env.run(TASK_COMPILE)).to.be.rejectedWith( Error, - "The 'optimize' setting with value 'true' is not supported for versions of the Vyper compiler older than 0.3.1 or newer than 0.3.10. You are currently using version 0.3.0." + "The 'optimize' setting with value 'true' is not supported for versions of the Vyper compiler older than or equal to 0.3.0 or newer than or equal to 0.3.10. You are currently using version 0.3.0." ); }); }); From 2f1dafe65ffb3f1d592d95a66b343b7cbdc6a9cf Mon Sep 17 00:00:00 2001 From: Christopher Dedominici <18092467+ChristopherDedominici@users.noreply.github.com> Date: Mon, 8 Apr 2024 12:01:16 +0200 Subject: [PATCH 10/12] smaller fixes based on PR's comments --- packages/hardhat-vyper/src/compiler.ts | 12 ++++++------ packages/hardhat-vyper/test/tests.ts | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/hardhat-vyper/src/compiler.ts b/packages/hardhat-vyper/src/compiler.ts index 134ea72bda..a2d74c33de 100644 --- a/packages/hardhat-vyper/src/compiler.ts +++ b/packages/hardhat-vyper/src/compiler.ts @@ -58,16 +58,16 @@ function getOptimize( compilerVersion: string, optimize: string | boolean | undefined ): string { - if (compilerVersion === "" && optimize !== undefined) { + if (optimize === undefined) { + return ""; + } + + if (compilerVersion === "") { throw new VyperPluginError( "The 'compilerVersion' parameter must be set when the setting 'optimize' is set." ); } - if (optimize === undefined) { - return ""; - } - if (typeof optimize === "boolean") { if (optimize) { if ( @@ -105,6 +105,6 @@ function getOptimize( } throw new VyperPluginError( - `The 'optimize' setting has an invalid type value. Type is: ${typeof optimize}.` + `The 'optimize' setting has an invalid type value: ${typeof optimize}. Type should be either string or boolean.` ); } diff --git a/packages/hardhat-vyper/test/tests.ts b/packages/hardhat-vyper/test/tests.ts index 721b16dae5..33e2409e20 100644 --- a/packages/hardhat-vyper/test/tests.ts +++ b/packages/hardhat-vyper/test/tests.ts @@ -159,7 +159,7 @@ describe("Vyper plugin", function () { it("should fail the compilation", async function () { await expect(this.env.run(TASK_COMPILE)).to.be.rejectedWith( Error, - "The 'optimize' setting has an invalid type value. Type is: number." + "The 'optimize' setting has an invalid type value: number. Type should be either string or boolean." ); }); }); From b85ff415930fe47012db7f47bed6fb0f04389dc7 Mon Sep 17 00:00:00 2001 From: Christopher Dedominici <18092467+ChristopherDedominici@users.noreply.github.com> Date: Mon, 8 Apr 2024 15:50:56 +0200 Subject: [PATCH 11/12] increase mocha timeout --- packages/hardhat-vyper/.mocharc.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/hardhat-vyper/.mocharc.json b/packages/hardhat-vyper/.mocharc.json index d2b0c6d38f..b21e04d8b4 100644 --- a/packages/hardhat-vyper/.mocharc.json +++ b/packages/hardhat-vyper/.mocharc.json @@ -1,5 +1,5 @@ { "require": "ts-node/register/files", "ignore": ["test/fixture-projects/**/*"], - "timeout": 25000 + "timeout": 40000 } From 598acb2c9be27d9616ab9c6300e53d5512b2d3e7 Mon Sep 17 00:00:00 2001 From: Christopher Dedominici <18092467+ChristopherDedominici@users.noreply.github.com> Date: Mon, 8 Apr 2024 22:26:01 +0200 Subject: [PATCH 12/12] add params in doc --- packages/hardhat-vyper/src/compiler.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/hardhat-vyper/src/compiler.ts b/packages/hardhat-vyper/src/compiler.ts index a2d74c33de..7d529a6527 100644 --- a/packages/hardhat-vyper/src/compiler.ts +++ b/packages/hardhat-vyper/src/compiler.ts @@ -9,6 +9,8 @@ export class Compiler { /** * * @param inputPaths array of paths to contracts to be compiled + * @param compilerVersion the version of the Vyper compiler + * @param settings the Vyper settings to use during compilation */ public async compile( inputPaths: string[],