-
Notifications
You must be signed in to change notification settings - Fork 358
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
extend utils & update compilation process #396
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,9 +3,11 @@ import path from "path"; | |
import { renderFile } from "template-file"; | ||
import { glob } from "fast-glob"; | ||
import { Command } from "commander"; | ||
import { needsRecompilation, deleteDir, setCompilationTime, isFolderEmpty } from "./utils"; | ||
|
||
const CONTRACTS_DIR = "contracts"; | ||
const OUTPUT_DIR = "contracts-preprocessed"; | ||
const TIMESTAMP_FILE = "last_compilation_preprocessing.timestamp"; // File to store the last compilation time | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do we need to add it to .gitignore? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
|
||
const params = { | ||
SYSTEM_CONTRACTS_OFFSET: "0x8000", | ||
|
@@ -17,6 +19,18 @@ async function preprocess(testMode: boolean) { | |
params.SYSTEM_CONTRACTS_OFFSET = "0x9000"; | ||
} | ||
|
||
const timestampFilePath = path.join(process.cwd(), TIMESTAMP_FILE); | ||
const folderToCheck = path.join(process.cwd(), CONTRACTS_DIR); | ||
|
||
if ((await isFolderEmpty(OUTPUT_DIR)) || needsRecompilation(folderToCheck, timestampFilePath)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not sure if it will work if:
Seems like on (2) the recompilation wont happen since no changes have been made to the contracts There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. updated |
||
console.log("Preprocessing needed."); | ||
await deleteDir("./contracts-preprocessed"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe use OUTPUT_DIR constant here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. updated |
||
setCompilationTime(timestampFilePath); | ||
} else { | ||
console.log("Preprocessing not needed."); | ||
return; | ||
} | ||
|
||
const contracts = await glob( | ||
[`${CONTRACTS_DIR}/**/*.sol`, `${CONTRACTS_DIR}/**/*.yul`, `${CONTRACTS_DIR}/**/*.zasm`], | ||
{ onlyFiles: true } | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,12 +7,13 @@ import type { Deployer } from "@matterlabs/hardhat-zksync-deploy"; | |
import type { BigNumberish, BytesLike } from "ethers"; | ||
import { BigNumber, ethers } from "ethers"; | ||
import * as fs from "fs"; | ||
import * as fsPr from "fs/promises"; | ||
import { hashBytecode } from "zksync-web3/build/src/utils"; | ||
import type { YulContractDescription, ZasmContractDescription } from "./constants"; | ||
import { Language, SYSTEM_CONTRACTS } from "./constants"; | ||
import { getCompilersDir } from "hardhat/internal/util/global-dir"; | ||
import path from "path"; | ||
import { spawn as _spawn } from "child_process"; | ||
import { spawn as _spawn, exec } from "child_process"; | ||
import { createHash } from "crypto"; | ||
import { CompilerDownloader } from "hardhat/internal/solidity/compiler/downloader"; | ||
|
||
|
@@ -253,3 +254,79 @@ export function prepareCompilerPaths(path: string): CompilerPaths { | |
|
||
return new CompilerPaths(absolutePathSources, absolutePathArtifacts); | ||
} | ||
|
||
// Get the latest file modification time in the watched folder | ||
function getLatestModificationTime(folder: string): Date | null { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add a comment on when it can return There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. comment added below |
||
const files = fs.readdirSync(folder); | ||
let latestTime: Date | null = null; | ||
|
||
files.forEach((file) => { | ||
const filePath = path.join(folder, file); | ||
const stats = fs.statSync(filePath); | ||
if (stats.isDirectory()) { | ||
const dirLatestTime = getLatestModificationTime(filePath); | ||
if (dirLatestTime && (!latestTime || dirLatestTime > latestTime)) { | ||
latestTime = dirLatestTime; | ||
} | ||
} else if (stats.isFile()) { | ||
if (!latestTime || stats.mtime > latestTime) { | ||
latestTime = stats.mtime; | ||
} | ||
} | ||
}); | ||
|
||
return latestTime; | ||
} | ||
|
||
// Read the last compilation timestamp from the file | ||
function getLastCompilationTime(timestampFile: string): Date | null { | ||
try { | ||
if (fs.existsSync(timestampFile)) { | ||
const timestamp = fs.readFileSync(timestampFile, "utf-8"); | ||
return new Date(parseInt(timestamp, 10)); | ||
} | ||
} catch (error) { | ||
const err = error as Error; // Cast `error` to `Error` | ||
console.error(`Error reading timestamp: ${err.message}`); | ||
} | ||
return null; | ||
} | ||
|
||
// Write the current time to the timestamp file | ||
export function setCompilationTime(timestampFile: string) { | ||
fs.writeFileSync(timestampFile, Date.now().toString()); | ||
} | ||
|
||
// Determine if recompilation is needed | ||
export function needsRecompilation(folder: string, timestampFile: string): boolean { | ||
const lastCompilationTime = getLastCompilationTime(timestampFile); | ||
const latestModificationTime = getLatestModificationTime(folder); | ||
|
||
if (!latestModificationTime || !lastCompilationTime) { | ||
return true; // If there's no history, always recompile | ||
} | ||
|
||
return latestModificationTime > lastCompilationTime; | ||
} | ||
|
||
export function deleteDir(path: string): Promise<void> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. rmdirSync? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. updated |
||
return new Promise((resolve, reject) => { | ||
exec(`rm -rf ${path}`, (error) => { | ||
if (error) { | ||
reject(error); // If an error occurs, reject the promise | ||
} else { | ||
resolve(); // If successful, resolve the promise | ||
} | ||
}); | ||
}); | ||
} | ||
|
||
export async function isFolderEmpty(folderPath: string): Promise<boolean> { | ||
try { | ||
const files = await fsPr.readdir(folderPath); // Get a list of files in the folder | ||
return files.length === 0; // If there are no files, the folder is empty | ||
} catch (error) { | ||
console.error("No target folder with artifacts."); | ||
return true; // Return true if an error, as folder doesn't exist. | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Checking the folder, rather than specific subfolders, like "contracts-preprocessed/precompiles/test-contracts".
If necessary, we can check each of the compilation targets separately