UNPKG

@nori-zk/proof-conversion

Version:

Verifying zkVM proofs inside o1js circuits, to generate Mina compatible proof

145 lines 8.05 kB
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var _ProcessPool_instances, _ProcessPool_free, _ProcessPool_lifo, _ProcessPool_logger, _ProcessPool_jobToString, _ProcessPool_spawnWorker, _ProcessPool_checkForJobsAfterWorkerFinish; import { spawn } from 'child_process'; import { Logger } from '../logging/logger.js'; import { InvertedPromise } from '../utils/InvertedPromise.js'; export function processCmdToString(processCmd) { const { cmd, args, printableArgs } = processCmd; if (!args.length) return cmd; if (!printableArgs) { return `${cmd} ${args.join(' ')}`; } const filteredPrintableArgs = args.filter((_, idx) => printableArgs.includes(idx)); return filteredPrintableArgs.length < args.length ? `${cmd} ${filteredPrintableArgs.join(' ')}...` : `${cmd} ${args.join(' ')}`; } let processPoolIdx = 0; export class ProcessPool { async runCommand(processCmd) { // Create an inverted promise to resolve the result at a later time. const invertedPromise = new InvertedPromise(); // Check for a free worker. const freeFreePoolWorkerKeyValuePair = __classPrivateFieldGet(this, _ProcessPool_free, "f").values().next().value; // If we have a free worker queue immediately. if (freeFreePoolWorkerKeyValuePair !== undefined) { // Get the worker Id const workerId = freeFreePoolWorkerKeyValuePair; // Remove the worker from the pool __classPrivateFieldGet(this, _ProcessPool_free, "f").delete(workerId); // Run job immediately __classPrivateFieldGet(this, _ProcessPool_instances, "m", _ProcessPool_spawnWorker).call(this, processCmd, workerId) .then((result) => invertedPromise.resolve(result)) .catch((err) => invertedPromise.reject(err)) .finally(() => __classPrivateFieldGet(this, _ProcessPool_instances, "m", _ProcessPool_checkForJobsAfterWorkerFinish).call(this, workerId)); return invertedPromise.promise; } else { // Queue job for next free worker __classPrivateFieldGet(this, _ProcessPool_logger, "f").debug(`No workers available. Job '${__classPrivateFieldGet(this, _ProcessPool_instances, "m", _ProcessPool_jobToString).call(this, processCmd)}' queued.`); __classPrivateFieldGet(this, _ProcessPool_lifo, "f").push({ ...processCmd, invertedPromise }); return invertedPromise.promise; } } workerFreeStatus() { return Array.from(__classPrivateFieldGet(this, _ProcessPool_free, "f")).sort((a, b) => a - b); } constructor(poolSize) { _ProcessPool_instances.add(this); _ProcessPool_free.set(this, void 0); _ProcessPool_lifo.set(this, []); _ProcessPool_logger.set(this, void 0); processPoolIdx++; __classPrivateFieldSet(this, _ProcessPool_free, new Set(Array.from({ length: poolSize }, (_, i) => i)), "f"); __classPrivateFieldSet(this, _ProcessPool_logger, new Logger(`ProcessPool${processPoolIdx}`), "f"); } } _ProcessPool_free = new WeakMap(), _ProcessPool_lifo = new WeakMap(), _ProcessPool_logger = new WeakMap(), _ProcessPool_instances = new WeakSet(), _ProcessPool_jobToString = function _ProcessPool_jobToString(processCmd) { return processCmdToString(processCmd); }, _ProcessPool_spawnWorker = async function _ProcessPool_spawnWorker(processCmd, workerId) { const printableProcessCmd = __classPrivateFieldGet(this, _ProcessPool_instances, "m", _ProcessPool_jobToString).call(this, processCmd); const startTime = Date.now(); __classPrivateFieldGet(this, _ProcessPool_logger, "f").log(`[Executor${workerId}] Attempting to execute cmd: '${printableProcessCmd}'.`); const { cmd, args } = processCmd; return new Promise((resolve, reject) => { let stdio; const capture = !!processCmd.capture; const emit = !!processCmd.emit; if (capture) stdio = 'pipe'; else if (emit) stdio = 'inherit'; else stdio = 'ignore'; let stdOut = ''; let stdErr = ''; // Spawn process const child = spawn(cmd, args, { stdio }); if (capture) { child.stdout?.on('data', (data) => { stdOut += data; if (emit) { process.stdout.write(data); } }); child.stderr?.on('data', (err) => { stdErr += err; if (emit) { process.stdout.write(err); } }); } let alreadyErrored = false; // Capture exit code child.on('error', (error) => { if (alreadyErrored) return; alreadyErrored = true; const message = `[Executor${workerId}] Cmd '${printableProcessCmd}' failed. ${error}`; __classPrivateFieldGet(this, _ProcessPool_logger, "f").warn(message); reject({ code: 1, stdErr, stdOut, error }); }); // Capture process close child.on('close', (code) => { if (code === 0) { __classPrivateFieldGet(this, _ProcessPool_logger, "f").log(`[Executor${workerId}] Cmd '${printableProcessCmd}' succeeded in ${(Date.now() - startTime) / 1000} seconds.`); resolve({ code, stdErr, stdOut }); } else { if (alreadyErrored) return; alreadyErrored = true; const stdErrTrimmed = stdErr.trim(); const message = `[Executor${workerId}] Cmd '${printableProcessCmd}' exited non zero code '${code}'${stdErrTrimmed ? `.\n${stdErrTrimmed}` : '.'}`; __classPrivateFieldGet(this, _ProcessPool_logger, "f").warn(message); reject({ code, stdErr, stdOut, error: new Error(message) }); } }); }); }, _ProcessPool_checkForJobsAfterWorkerFinish = async function _ProcessPool_checkForJobsAfterWorkerFinish(workerId) { // Free ourselves __classPrivateFieldGet(this, _ProcessPool_free, "f").add(workerId); // Check the status of the lifo queue, exit if there is nothing to do. const job = __classPrivateFieldGet(this, _ProcessPool_lifo, "f").pop(); if (!job) return; // This worker is now considered busy with the taken job __classPrivateFieldGet(this, _ProcessPool_free, "f").delete(workerId); // Run the job and resolve/reject the inverted promise on completion / error. __classPrivateFieldGet(this, _ProcessPool_instances, "m", _ProcessPool_spawnWorker).call(this, job, workerId) .then((result) => job.invertedPromise.resolve(result)) .catch((err) => job.invertedPromise.reject(err)) .finally(() => __classPrivateFieldGet(this, _ProcessPool_instances, "m", _ProcessPool_checkForJobsAfterWorkerFinish).call(this, workerId)); }; //# sourceMappingURL=processPool.js.map