@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
JavaScript
;
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29saWRpdHlDb21waWxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saWIvc29saWRpdHlDb21waWxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQWtCQSw0Q0FXQztBQVlELGtEQW9GQztBQUVELDhDQWtCQztBQTBGRCw4QkF5QkM7QUFwUUQsd0NBQXdDO0FBQ3hDLGdEQUF3QjtBQUN4Qiw0Q0FBb0I7QUFDcEIsaURBQTBDO0FBQzFDLG9EQUE0QjtBQUM1QixtREFBdUQ7QUFDdkQsc0NBQWlFO0FBQ2pFLHFDQUF1RDtBQU12RCw4REFBOEQ7QUFDOUQsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBRTdCLE1BQU0sY0FBYyxHQUFHLG9DQUFvQyxDQUFDO0FBRTVELFNBQWdCLGdCQUFnQjtJQUM5QixJQUFJLE9BQU8sQ0FBQyxRQUFRLEtBQUssUUFBUSxJQUFJLE9BQU8sQ0FBQyxJQUFJLEtBQUssS0FBSyxFQUFFLENBQUM7UUFDNUQsT0FBTyxjQUFjLENBQUM7SUFDeEIsQ0FBQztJQUNELElBQUksT0FBTyxDQUFDLFFBQVEsS0FBSyxPQUFPLElBQUksT0FBTyxDQUFDLElBQUksS0FBSyxLQUFLLEVBQUUsQ0FBQztRQUMzRCxPQUFPLGFBQWEsQ0FBQztJQUN2QixDQUFDO0lBQ0QsSUFBSSxPQUFPLENBQUMsUUFBUSxLQUFLLE9BQU8sSUFBSSxPQUFPLENBQUMsSUFBSSxLQUFLLEtBQUssRUFBRSxDQUFDO1FBQzNELE9BQU8sZUFBZSxDQUFDO0lBQ3pCLENBQUM7SUFDRCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUM7QUFDRDs7Ozs7Ozs7O0dBU0c7QUFFSSxLQUFLLFVBQVUsbUJBQW1CLENBQ3ZDLFlBQW9CLEVBQ3BCLGVBQXVCLEVBQ3ZCLE9BQWUsRUFDZixhQUFnQyxFQUNoQyxlQUFlLEdBQUcsS0FBSzs7SUFFdkIs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