UNPKG

@ethereum-sourcify/compilers

Version:

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

139 lines 10.8 kB
// TODO: Handle nodejs only dependencies import path from 'path'; import fs from 'fs'; import { spawnSync } from 'child_process'; import { asyncExec, CompilerError, fetchWithBackoff } from './common'; import { logDebug, logError, logInfo, logWarn } from '../logger'; const HOST_VYPER_REPO = 'https://github.com/vyperlang/vyper/releases/download/'; export function findVyperPlatform() { if (process.platform === 'darwin' && (process.arch === 'x64' || process.arch === 'arm64')) { return 'darwin'; } if (process.platform === 'linux' && process.arch === 'x64') { return 'linux'; } if (process.platform === 'win32' && process.arch === 'x64') { return 'windows.exe'; } return false; } /** * Searches for a vyper compiler: first for a local executable version, then from HOST_VYPER_REPO * Once the compiler is retrieved, it is used, and the stringified vyper output is returned. * * @param version the version of vyper to be used for compilation * @param input a JSON object of the standard-json format compatible with vyper * @param log the logger * @returns stringified vyper output */ export async function useVyperCompiler(vyperRepoPath, version, vyperJsonInput) { const vyperPlatform = findVyperPlatform(); if (!vyperPlatform) { throw new Error('Vyper is not supported on this machine.'); } const vyperPath = await getVyperExecutable(vyperRepoPath, vyperPlatform, version); let compiled; const inputStringified = JSON.stringify(vyperJsonInput); const startCompilation = Date.now(); try { compiled = await asyncExec(`${vyperPath} --standard-json`, inputStringified, 250 * 1024 * 1024); } catch (error) { if (error?.code === 'ENOBUFS') { throw new Error('Compilation output size too large'); } logWarn(error.message); throw error; } const endCompilation = Date.now(); logInfo('Local compiler - Compilation done', { compiler: 'vyper', timeInMs: endCompilation - startCompilation, }); if (!compiled) { throw new Error('Compilation failed. No output from the compiler.'); } const compiledJSON = JSON.parse(compiled); const errorMessages = compiledJSON?.errors?.filter((e) => e.severity === 'error'); if (errorMessages && errorMessages.length > 0) { logError('Compiler error', { errorMessages, }); throw new CompilerError('Compiler error', errorMessages); } return compiledJSON; } export async function getVyperExecutable(vyperRepoPath, platform, version) { const fileName = `vyper.${version}.${platform}`; const vyperPath = path.join(vyperRepoPath, fileName); if (validateVyperPath(vyperPath)) { return vyperPath; } await fetchAndSaveVyper(platform, vyperPath, version, fileName); // Validate the vyper path if (!validateVyperPath(vyperPath)) { throw new Error(`Vyper not found. Maybe an incorrect version was provided. ${vyperPath} - ${version} - ${platform}`); } return vyperPath; } function validateVyperPath(vyperPath) { if (!fs.existsSync(vyperPath)) { logDebug('Vyper binary not found', { vyperPath, }); return false; } // TODO: Handle nodejs only dependencies const spawned = spawnSync(vyperPath, ['--version']); if (spawned.status === 0) { logDebug('Found vyper binary', { vyperPath, }); return true; } const error = spawned?.error?.message || spawned.stderr.toString() || 'Error running vyper, are you on the right platform? (e.g. x64 vs arm)'; logWarn(error); return false; } /** * Fetches a vyper binary and saves it to the given path. */ async function fetchAndSaveVyper(platform, vyperPath, version, fileName) { const encodedURIFilename = encodeURIComponent(fileName); const versionWithoutCommit = version.split('+')[0]; const githubVyperURI = `${HOST_VYPER_REPO}v${versionWithoutCommit}/${encodedURIFilename}`; logDebug('Fetching vyper', { version, platform, vyperPath, githubVyperURI, }); const res = await fetchWithBackoff(githubVyperURI); const status = res.status; const buffer = await res.arrayBuffer(); if (status === 200 && buffer) { logDebug('Fetched vyper', { version, platform, vyperPath }); fs.mkdirSync(path.dirname(vyperPath), { recursive: true }); try { fs.unlinkSync(vyperPath); } catch (_e) { undefined; } fs.writeFileSync(vyperPath, new DataView(buffer), { mode: 0o755 }); return; } else { logError('Failed fetching vyper', { version, platform, vyperPath, githubVyperURI, }); throw new Error(`Failed fetching vyper ${version} for platform ${platform}. Please check if the version is valid.`); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidnlwZXJDb21waWxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saWIvdnlwZXJDb21waWxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSx3Q0FBd0M7QUFDeEMsT0FBTyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBQ3hCLE9BQU8sRUFBRSxNQUFNLElBQUksQ0FBQztBQUNwQixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsYUFBYSxFQUFFLGdCQUFnQixFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQ3RFLE9BQU8sRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFNakUsTUFBTSxlQUFlLEdBQUcsdURBQXVELENBQUM7QUFFaEYsTUFBTSxVQUFVLGlCQUFpQjtJQUMvQixJQUNFLE9BQU8sQ0FBQyxRQUFRLEtBQUssUUFBUTtRQUM3QixDQUFDLE9BQU8sQ0FBQyxJQUFJLEtBQUssS0FBSyxJQUFJLE9BQU8sQ0FBQyxJQUFJLEtBQUssT0FBTyxDQUFDLEVBQ3BELENBQUM7UUFDRCxPQUFPLFFBQVEsQ0FBQztJQUNsQixDQUFDO0lBQ0QsSUFBSSxPQUFPLENBQUMsUUFBUSxLQUFLLE9BQU8sSUFBSSxPQUFPLENBQUMsSUFBSSxLQUFLLEtBQUssRUFBRSxDQUFDO1FBQzNELE9BQU8sT0FBTyxDQUFDO0lBQ2pCLENBQUM7SUFDRCxJQUFJLE9BQU8sQ0FBQyxRQUFRLEtBQUssT0FBTyxJQUFJLE9BQU8sQ0FBQyxJQUFJLEtBQUssS0FBSyxFQUFFLENBQUM7UUFDM0QsT0FBTyxhQUFhLENBQUM7SUFDdkIsQ0FBQztJQUNELE9BQU8sS0FBSyxDQUFDO0FBQ2YsQ0FBQztBQUNEOzs7Ozs7OztHQVFHO0FBRUgsTUFBTSxDQUFDLEtBQUssVUFBVSxnQkFBZ0IsQ0FDcEMsYUFBcUIsRUFDckIsT0FBZSxFQUNm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