@nori-zk/proof-conversion
Version:
Verifying zkVM proofs inside o1js circuits, to generate Mina compatible proof
145 lines • 8.06 kB
JavaScript
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 'esm-iso-logger';
import { DeferredPromise } from '../utils/DeferredPromise.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 deferredPromise = new DeferredPromise();
// 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) => deferredPromise.resolve(result))
.catch((err) => deferredPromise.reject(err))
.finally(() => __classPrivateFieldGet(this, _ProcessPool_instances, "m", _ProcessPool_checkForJobsAfterWorkerFinish).call(this, workerId));
return deferredPromise.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, deferredPromise: deferredPromise });
return deferredPromise.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.deferredPromise.resolve(result))
.catch((err) => job.deferredPromise.reject(err))
.finally(() => __classPrivateFieldGet(this, _ProcessPool_instances, "m", _ProcessPool_checkForJobsAfterWorkerFinish).call(this, workerId));
};
//# sourceMappingURL=processPool.js.map