Skip to content

Commit adb0116

Browse files
committed
refactor: use spawn instead of exec
1 parent eb42205 commit adb0116

File tree

2 files changed

+44
-25
lines changed

2 files changed

+44
-25
lines changed

packages/contracts/sdk/mpc/MpcNetworkService.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,11 @@ async function proveAsParty(params: {
138138
fs.writeFileSync(circuitPath, JSON.stringify(params.circuit));
139139

140140
const runCommand = makeRunCommand(__dirname);
141-
await runCommand(
142-
`./run-party.sh ${workingDir} ${circuitPath} ${params.partyIndex}`,
143-
);
141+
await runCommand("./run-party.sh", [
142+
workingDir,
143+
circuitPath,
144+
params.partyIndex,
145+
]);
144146

145147
const { proof, publicInputs } = decodeNativeHonkProof(
146148
fs.readFileSync(

packages/contracts/sdk/mpc/utils.ts

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export async function splitInput(circuit: CompiledCircuit, input: InputMap) {
1313
const circuitPath = path.join(workingDir, "circuit.json");
1414
fs.writeFileSync(circuitPath, JSON.stringify(circuit));
1515
const runCommand = makeRunCommand(__dirname);
16-
await runCommand(`./split-inputs.sh ${proverPath} ${circuitPath}`);
16+
await runCommand("./split-inputs.sh", [proverPath, circuitPath]);
1717
const shared = range(3).map((i) => {
1818
const x = Uint8Array.from(fs.readFileSync(`${proverPath}.${i}.shared`));
1919
return ethers.hexlify(x);
@@ -36,25 +36,42 @@ export async function inWorkingDir<T>(f: (workingDir: string) => Promise<T>) {
3636
}
3737
}
3838

39-
export const makeRunCommand = (cwd?: string) => async (command: string) => {
40-
const { exec } = await import("child_process");
41-
const { promisify } = await import("util");
42-
const execAsync = promisify(exec);
43-
// TODO(security): escape command arguments (use spawn)
44-
try {
45-
const { stdout, stderr } = await execAsync(command, {
46-
cwd,
47-
maxBuffer: Infinity,
39+
export const makeRunCommand =
40+
(cwd?: string) =>
41+
async (command: string, args: (string | number)[] = []) => {
42+
const { spawn } = await import("node:child_process");
43+
44+
const spawned = spawn(
45+
command,
46+
args.map((arg) => arg.toString()),
47+
{ cwd },
48+
);
49+
spawned.stdout.on("data", (data) => {
50+
process.stdout.write(data);
4851
});
49-
if (stdout) {
50-
console.log(stdout);
51-
}
52-
if (stderr) {
53-
console.error(stderr);
54-
}
55-
} catch (error) {
56-
console.error(`Error executing command: ${command}`);
57-
console.error((error as any).stderr || (error as any).message);
58-
throw new Error(`Error executing command: ${command}`);
59-
}
60-
};
52+
53+
spawned.stderr.on("data", (data) => {
54+
process.stderr.write(data);
55+
});
56+
57+
return await new Promise<void>((resolve, reject) => {
58+
spawned.on("close", (code: number) => {
59+
if (code !== 0) {
60+
reject(new Error(`Process exited with code ${code}`));
61+
return;
62+
}
63+
64+
resolve();
65+
});
66+
67+
spawned.on("error", (err) => {
68+
reject(
69+
new Error(
70+
`Error executing command \`${
71+
command + " " + args.join(" ")
72+
}\`: ${err.message}`,
73+
),
74+
);
75+
});
76+
});
77+
};

0 commit comments

Comments
 (0)