@ethereum-sourcify/compilers
Version:
Wrapper around multiple compilers to download the right version and invoke the compilation with a common interface.
148 lines • 11.3 kB
JavaScript
// TODO: Handle nodejs only dependencies
import path from 'path';
import fs from 'fs';
import { spawnSync } from 'child_process';
import { asyncExec, 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);
if (!vyperPath) {
throw new Error('Vyper path not found. Maybe an incorrect version was provided.');
}
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) {
const error = new Error('Compiler error:\n ' + JSON.stringify(errorMessages));
logError(error.message);
throw error;
}
return compiledJSON;
}
export async function getVyperExecutable(vyperRepoPath, platform, version) {
const fileName = `vyper.${version}.${platform}`;
const vyperPath = path.join(vyperRepoPath, fileName);
if (fs.existsSync(vyperPath) && validateVyperPath(vyperPath)) {
logDebug('Found vyper binary', {
version,
vyperPath,
platform,
});
return vyperPath;
}
logDebug('Downloading vyper', {
version,
vyperPath,
platform,
});
const success = await fetchAndSaveVyper(platform, vyperPath, version, fileName);
if (success) {
logDebug('Downloaded vyper', {
version,
vyperPath,
platform,
});
}
if (success && !validateVyperPath(vyperPath)) {
logError('Cannot validate vyper', {
version,
vyperPath,
platform,
});
return null;
}
return success ? vyperPath : null;
}
function validateVyperPath(vyperPath) {
// TODO: Handle nodejs only dependencies
const spawned = spawnSync(vyperPath, ['--version']);
if (spawned.status === 0) {
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 true;
}
else {
logWarn('Failed fetching vyper', { version, platform, vyperPath });
}
return false;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidnlwZXJDb21waWxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saWIvdnlwZXJDb21waWxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSx3Q0FBd0M7QUFDeEMsT0FBTyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBQ3hCLE9BQU8sRUFBRSxNQUFNLElBQUksQ0FBQztBQUNwQixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDdkQsT0FBTyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFdBQVcsQ0FBQztBQU1qRSxNQUFNLGVBQWUsR0FBRyx1REFBdUQsQ0FBQztBQUVoRixNQUFNLFVBQVUsaUJBQWlCO0lBQy9CLElBQ0UsT0FBTyxDQUFDLFFBQVEsS0FBSyxRQUFRO1FBQzdCLENBQUMsT0FBTyxDQUFDLElBQUksS0FBSyxLQUFLLElBQUksT0FBTyxDQUFDLElBQUksS0FBSyxPQUFPLENBQUMsRUFDcEQsQ0FBQztRQUNELE9BQU8sUUFBUSxDQUFDO0lBQ2xCLENBQUM7SUFDRCxJQUFJLE9BQU8sQ0FBQyxRQUFRLEtBQUssT0FBTyxJQUFJLE9BQU8sQ0FBQyxJQUFJLEtBQUssS0FBSyxFQUFFLENBQUM7UUFDM0QsT0FBTyxPQUFPLENBQUM7SUFDakIsQ0FBQztJQUNELElBQUksT0FBTyxDQUFDLFFBQVEsS0FBSyxPQUFPLElBQUksT0FBTyxDQUFDLElBQUksS0FBSyxLQUFLLEVBQUUsQ0FBQztRQUMzRCxPQUFPLGFBQWEsQ0FBQztJQUN2QixDQUFDO0lBQ0QsT0FBTyxLQUFLLENBQUM7QUFDZixDQUFDO0FBQ0Q7Ozs7Ozs7O0dBUUc7QUFFSCxNQUFNLENBQUMsS0FBSyxVQUFVLGdCQUFnQixDQUNwQyxhQUFxQixFQUNyQixPQUFlLEVBQ2YsY0FBOEI7SUFF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