UNPKG

@ethereum-sourcify/compilers

Version:

Wrapper around multiple compilers to download the right version and invoke the compilation with a common interface.

260 lines 20.2 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.findSolcPlatform = findSolcPlatform; exports.useSolidityCompiler = useSolidityCompiler; exports.getSolcExecutable = getSolcExecutable; exports.getSolcJs = getSolcJs; // TODO: Handle nodejs only dependencies const path_1 = __importDefault(require("path")); const fs_1 = __importDefault(require("fs")); const child_process_1 = require("child_process"); const semver_1 = __importDefault(require("semver")); const worker_threads_1 = require("worker_threads"); const logger_1 = require("../logger"); const common_1 = require("./common"); // eslint-disable-next-line @typescript-eslint/no-var-requires const solc = require('solc'); const HOST_SOLC_REPO = 'https://binaries.soliditylang.org/'; function findSolcPlatform() { if (process.platform === 'darwin' && process.arch === 'x64') { return 'macosx-amd64'; } if (process.platform === 'linux' && process.arch === 'x64') { return 'linux-amd64'; } if (process.platform === 'win32' && process.arch === 'x64') { return 'windows-amd64'; } return false; } /** * Searches for a solc: first for a local executable version, then from HOST_SOLC_REPO * and then using the getSolcJs function. * Once the compiler is retrieved, it is used, and the stringified solc output is returned. * * @param version the version of solc to be used for compilation * @param input a JSON object of the standard-json format compatible with solc * @param log the logger * @returns stringified solc output */ async function useSolidityCompiler(solcRepoPath, solJsonRepoPath, version, solcJsonInput, forceEmscripten = false) { var _a, _b, _c; // For nightly builds, Solidity version is saved as 0.8.17-ci.2022.8.9+commit.6b60524c instead of 0.8.17-nightly.2022.8.9+commit.6b60524c. // Not possible to retrieve compilers with "-ci.". if (version.includes('-ci.')) version = version.replace('-ci.', '-nightly.'); const inputStringified = JSON.stringify(solcJsonInput); let compiled; const solcPlatform = findSolcPlatform(); let solcPath; if (solcPlatform && !forceEmscripten) { solcPath = await getSolcExecutable(solcRepoPath, solcPlatform, version); } let startCompilation; if (solcPath && !forceEmscripten) { (0, logger_1.logInfo)('Compiling with solc binary', { version, solcPath }); startCompilation = Date.now(); try { compiled = await (0, common_1.asyncExec)(`${solcPath} --standard-json`, inputStringified, 250 * 1024 * 1024); } catch (error) { if ((error === null || error === void 0 ? void 0 : error.code) === 'ENOBUFS') { throw new Error('Compilation output size too large'); } throw error; } } else { (0, logger_1.logInfo)('Compiling with solc-js', { version }); const solJson = await getSolcJs(solJsonRepoPath, version); startCompilation = Date.now(); if (solJson) { const coercedVersion = (_b = (_a = semver_1.default.coerce(new semver_1.default.SemVer(version))) === null || _a === void 0 ? void 0 : _a.version) !== null && _b !== void 0 ? _b : ''; // Run Worker for solc versions < 0.4.0 for clean compiler context. See https://github.com/ethereum/sourcify/issues/1099 if (semver_1.default.lt(coercedVersion, '0.4.0')) { compiled = await new Promise((resolve, reject) => { const worker = importWorker(path_1.default.resolve(__dirname, './compilerWorker.ts'), { workerData: { solJsonRepoPath, version, inputStringified }, }); worker.once('message', (result) => { resolve(result); }); worker.once('error', (error) => { reject(error); }); }); } else { compiled = solJson.compile(inputStringified); } } } const endCompilation = Date.now(); (0, logger_1.logInfo)('Local compiler - Compilation done', { compiler: 'solidity', timeInMs: endCompilation - startCompilation, }); if (!compiled) { throw new Error('Compilation failed. No output from the compiler.'); } const compiledJSON = JSON.parse(compiled); const errorMessages = (_c = compiledJSON === null || compiledJSON === void 0 ? void 0 : compiledJSON.errors) === null || _c === void 0 ? void 0 : _c.filter((e) => e.severity === 'error'); if (errorMessages && errorMessages.length > 0) { const error = new Error('Compiler error:\n ' + JSON.stringify(errorMessages)); (0, logger_1.logError)(error.message); throw error; } return compiledJSON; } async function getSolcExecutable(solcRepoPath, platform, version) { const fileName = `solc-${platform}-v${version}`; const solcPath = path_1.default.join(solcRepoPath, fileName); if (fs_1.default.existsSync(solcPath) && validateSolcPath(solcPath)) { (0, logger_1.logDebug)('Found existing solc', { version, platform, solcPath }); return solcPath; } const success = await fetchAndSaveSolc(platform, solcPath, version, fileName); if (success && !validateSolcPath(solcPath)) { (0, logger_1.logError)(`Cannot validate solc ${version}.`); return null; } return success ? solcPath : null; } function validateSolcPath(solcPath) { var _a; // TODO: Handle nodejs only dependencies const spawned = (0, child_process_1.spawnSync)(solcPath, ['--version']); if (spawned.status === 0) { return true; } const error = ((_a = spawned === null || spawned === void 0 ? void 0 : spawned.error) === null || _a === void 0 ? void 0 : _a.message) || spawned.stderr.toString() || 'Error running solc, are you on the right platoform? (e.g. x64 vs arm)'; (0, logger_1.logWarn)(error); return false; } /** * Fetches a solc binary and saves it to the given path. * * If platform is "bin", it will download the solc-js binary. */ async function fetchAndSaveSolc(platform, solcPath, version, fileName) { const encodedURIFilename = encodeURIComponent(fileName); const githubSolcURI = `${HOST_SOLC_REPO}${platform}/${encodedURIFilename}`; (0, logger_1.logInfo)('Fetching solc', { version, platform, githubSolcURI, solcPath }); let res = await (0, common_1.fetchWithBackoff)(githubSolcURI); let status = res.status; let buffer; // handle case in which the response is a link to another version if (status === 200) { buffer = await res.arrayBuffer(); const responseText = Buffer.from(buffer).toString(); if (/^([\w-]+)-v(\d+\.\d+\.\d+)\+commit\.([a-fA-F0-9]+).*$/.test(responseText)) { const githubSolcURI = `${HOST_SOLC_REPO}${platform}/${responseText}`; res = await (0, common_1.fetchWithBackoff)(githubSolcURI); status = res.status; buffer = await res.arrayBuffer(); } } if (status === 200 && buffer) { fs_1.default.mkdirSync(path_1.default.dirname(solcPath), { recursive: true }); try { fs_1.default.unlinkSync(solcPath); } catch (_e) { undefined; } fs_1.default.writeFileSync(solcPath, new DataView(buffer), { mode: 0o755 }); (0, logger_1.logInfo)('Saved solc', { version, platform, githubSolcURI, solcPath }); return true; } else { (0, logger_1.logWarn)('Failed fetching solc', { version, platform, githubSolcURI, solcPath, }); } return false; } /** * Fetches the requested version of the Solidity compiler (soljson). * First attempts to search locally; if that fails, falls back to downloading it. * * @param version the solc version to retrieve: the expected format is * * "[v]<major>.<minor>.<patch>+commit.<hash>" * * e.g.: "0.6.6+commit.6c089d02" * * defaults to "latest" * * @param log a logger to track the course of events * * @returns the requested solc instance */ async function getSolcJs(solJsonRepoPath, version) { // /^\d+\.\d+\.\d+\+commit\.[a-f0-9]{8}$/ version = version.trim(); if (version !== 'latest' && !version.startsWith('v')) { version = 'v' + version; } const fileName = `soljson-${version}.js`; const solJsonPath = path_1.default.resolve(solJsonRepoPath, fileName); if (!fs_1.default.existsSync(solJsonPath)) { (0, logger_1.logDebug)('Solc-js not found locally, downloading', { version, solJsonPath, }); if (!(await fetchAndSaveSolc('bin', solJsonPath, version, fileName))) { return false; } } const solcjsImports = await Promise.resolve(`${solJsonPath}`).then(s => __importStar(require(s))); return solc.setupMethods(solcjsImports); } // https://stackoverflow.com/questions/71795469/ts-node-using-worker-thread-cause-cannot-use-import-statement-outside-a-module function importWorker(path, options) { const resolvedPath = require.resolve(path); return new worker_threads_1.Worker(resolvedPath, Object.assign(Object.assign({}, options), { execArgv: /\.ts$/.test(resolvedPath) ? ['--require', 'ts-node/register'] : undefined })); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29saWRpdHlDb21waWxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saWIvc29saWRpdHlDb21waWxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQWNBLDRDQVdDO0FBWUQsa0RBb0ZDO0FBRUQsOENBa0JDO0FBMEZELDhCQXlCQztBQWhRRCx3Q0FBd0M7QUFDeEMsZ0RBQXdCO0FBQ3hCLDRDQUFvQjtBQUNwQixpREFBMEM7QUFDMUMsb0RBQTRCO0FBQzVCLG1EQUF1RDtBQUN2RCxzQ0FBaUU7QUFDakUscUNBQXVEO0FBRXZELDhEQUE4RDtBQUM5RCxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7QUFFN0IsTUFBTSxjQUFjLEdBQUcsb0NBQW9DLENBQUM7QUFFNUQsU0FBZ0IsZ0JBQWdCO0lBQzlCLElBQUksT0FBTyxDQUFDLFFBQVEsS0FBSyxRQUFRLElBQUksT0FBTyxDQUFDLElBQUksS0FBSyxLQUFLLEVBQUUsQ0FBQztRQUM1RCxPQUFPLGNBQWMsQ0FBQztJQUN4QixDQUFDO0lBQ0QsSUFBSSxPQUFPLENBQUMsUUFBUSxLQUFLLE9BQU8sSUFBSSxPQUFPLENBQUMsSUFBSSxLQUFLLEtBQUssRUFBRSxDQUFDO1FBQzNELE9BQU8sYUFBYSxDQUFDO0lBQ3ZCLENBQUM7SUFDRCxJQUFJLE9BQU8sQ0FBQyxRQUFRLEtBQUssT0FBTyxJQUFJLE9BQU8sQ0FBQyxJQUFJLEtBQUssS0FBSyxFQUFFLENBQUM7UUFDM0QsT0FBTyxlQUFlLENBQUM7SUFDekIsQ0FBQztJQUNELE9BQU8sS0FBSyxDQUFDO0FBQ2YsQ0FBQztBQUNEOzs7Ozs7Ozs7R0FTRztBQUVJLEtBQUssVUFBVSxtQkFBbUIsQ0FDdkMsWUFBb0IsRUFDcEIsZUFBdUIsRUFDdkIsT0FBZSxFQUNmLGFBQWtCLEVBQ2xCLGVBQWUsR0FBRyxLQUFLOztJQUV2Qiww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