Skip to content

Commit b2074d0

Browse files
author
Duncan Westland
authored
Merge pull request #19 from EYBlockchain/liju.jose/concurrent-generate-proof-fix
bug of concurrent generateProof fixed
2 parents ea83ebd + 6fc6a6a commit b2074d0

File tree

11 files changed

+228
-299
lines changed

11 files changed

+228
-299
lines changed

src/queues/generateKeys.mjs

Lines changed: 6 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,22 @@
1-
import fs from 'fs';
2-
import path from 'path';
3-
import zokrates from '@eyblockchain/zokrates-zexe.js';
41
import rabbitmq from '../utils/rabbitmq.mjs';
52
import logger from '../utils/logger.mjs';
3+
import generateKeys from '../services/generateKeys.mjs';
64

75
export default function receiveMessage() {
8-
const outputPath = `./output`;
9-
const circuitsPath = `./circuits`;
10-
116
rabbitmq.receiveMessage('generate-keys', async message => {
12-
const { filepath, curve = 'bls12_377', backend = 'zexe', provingScheme = 'gm17' } = JSON.parse(
13-
message.content.toString(),
14-
);
157
const { replyTo, correlationId } = message.properties;
168
const response = {
179
error: null,
1810
data: null,
1911
};
2012

2113
try {
22-
const ext = path.extname(filepath);
23-
const circuitName = path.basename(filepath, '.zok'); // filename without '.zok'
24-
const circuitDir = filepath.replace(ext, '');
25-
26-
fs.mkdirSync(`${outputPath}/${circuitDir}`, { recursive: true });
27-
28-
logger.info('Compile...');
29-
await zokrates.compile(
30-
`${circuitsPath}/${filepath}`,
31-
`${outputPath}/${circuitDir}`,
32-
`${circuitName}_out`,
33-
curve,
34-
);
35-
36-
logger.info('Setup...');
37-
await zokrates.setup(
38-
`${outputPath}/${circuitDir}/${circuitName}_out`,
39-
`${outputPath}/${circuitDir}`,
40-
provingScheme,
41-
backend,
42-
`${circuitName}_vk`,
43-
`${circuitName}_pk`,
44-
);
45-
46-
const vk = await zokrates.extractVk(`${outputPath}/${circuitDir}/${circuitName}_vk.key`);
47-
48-
logger.info(`Complete ${filepath}`);
49-
50-
response.data = { vk, filepath };
14+
response.data = await generateKeys(JSON.parse(
15+
message.content.toString(),
16+
));
5117
} catch (err) {
52-
response.error = err;
18+
logger.error('Error in generate-keys', err);
19+
response.error = 'Key generation failed';
5320
}
5421

5522
rabbitmq.sendMessage(replyTo, response, { correlationId });

src/queues/generateProof.mjs

Lines changed: 7 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,27 @@
1-
import fs from 'fs';
2-
import util from 'util';
3-
import zokrates from '@eyblockchain/zokrates-zexe.js';
4-
import path from 'path';
51
import rabbitmq from '../utils/rabbitmq.mjs';
6-
import { getProofByCircuitPath } from '../utils/filing.mjs';
72
import logger from '../utils/logger.mjs';
8-
9-
const unlink = util.promisify(fs.unlink);
3+
import generateProof from '../services/generateProof.mjs';
104

115
export default function receiveMessage() {
12-
const outputPath = `./output/`;
13-
146
rabbitmq.receiveMessage('generate-proof', async message => {
157
const { replyTo, correlationId } = message.properties;
16-
const {
17-
folderpath,
18-
inputs,
19-
transactionInputs,
20-
outputDirectoryPath,
21-
proofFileName,
22-
backend = 'zexe',
23-
provingScheme = 'gm17',
24-
} = JSON.parse(message.content.toString());
258

269
const response = {
2710
error: null,
2811
data: null,
2912
};
3013

31-
const circuitName = path.basename(folderpath);
32-
33-
// Delete previous witness/proof files if they exist.
34-
// Prevents bad inputs from going through anyway.
35-
try {
36-
await unlink(`${outputPath}/${folderpath}/${circuitName}_witness`);
37-
await unlink(`${outputPath}/${folderpath}/${circuitName}_proof.json`);
38-
} catch {
39-
// No files to delete. Do nothing.
40-
}
41-
42-
const opts = {};
43-
opts.createFile = true;
44-
opts.directory = `./output/${folderpath}` || outputDirectoryPath;
45-
opts.fileName = `${circuitName}_proof.json` || proofFileName;
46-
4714
try {
48-
logger.info('Compute witness...');
49-
await zokrates.computeWitness(
50-
`${outputPath}/${folderpath}/${circuitName}_out`,
51-
`${outputPath}/${folderpath}/`,
52-
`${circuitName}_witness`,
53-
inputs,
54-
);
55-
56-
logger.info('Generate proof...');
57-
await zokrates.generateProof(
58-
`${outputPath}/${folderpath}/${circuitName}_pk.key`,
59-
`${outputPath}/${folderpath}/${circuitName}_out`,
60-
`${outputPath}/${folderpath}/${circuitName}_witness`,
61-
provingScheme,
62-
backend,
63-
opts,
64-
);
65-
66-
const { proof, inputs: publicInputs } = await getProofByCircuitPath(folderpath);
67-
68-
logger.info(`Complete`);
69-
logger.debug(`Responding with proof and inputs:`);
70-
logger.debug(proof);
71-
logger.debug(publicInputs);
72-
73-
response.data = { proof, inputs: publicInputs, transactionInputs };
15+
response.data = await generateProof(JSON.parse(
16+
message.content.toString(),
17+
));
7418
} catch (err) {
19+
logger.error('Error in generate-proof', err);
7520
response.error = 'Proof generation failed';
7621
}
7722

78-
rabbitmq.sendMessage(replyTo, response, { correlationId, type: folderpath });
23+
24+
rabbitmq.sendMessage(replyTo, response, { correlationId });
7925
rabbitmq.sendACK(message);
8026
});
8127
}

src/queues/loadCircuits.mjs

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
1-
import fs from 'fs';
2-
31
import rabbitmq from '../utils/rabbitmq.mjs';
4-
import { untarFiles, deleteFile, getFilesRecursively } from '../utils/filing.mjs';
2+
import logger from '../utils/logger.mjs';
3+
import loadCircuits from '../services/loadCircuits.mjs';
54

65
export default function receiveMessage() {
7-
const outputPath = `./circuits/`;
8-
96
rabbitmq.receiveMessage('load-circuits', async message => {
107
const circuits = JSON.parse(message.content.toString());
118
const { replyTo, correlationId } = message.properties;
@@ -15,28 +12,10 @@ export default function receiveMessage() {
1512
};
1613

1714
try {
18-
if (!circuits.name.endsWith('.tar')) {
19-
throw Error(`Expected an archive file with extension '.tar'. Got ${circuits.name}`);
20-
}
21-
fs.writeFileSync(`${outputPath}${circuits.name}`, circuits.data);
22-
23-
// unarchive the circuit files
24-
await untarFiles('/app/circuits', circuits.name);
25-
26-
// get a list of files from the unarchived folder
27-
const files = await getFilesRecursively(`/app/circuits/${circuits.name.replace('.tar', '')}`);
28-
files.forEach(file => {
29-
if (!file.endsWith('.zok')) {
30-
throw Error('For shame, this is not an .zok file');
31-
}
32-
return null;
33-
});
34-
35-
// delete the archive file
36-
await deleteFile(`${outputPath}${circuits.name}`);
37-
response.data = { message: 'Circuits loadded successfully' };
15+
response.data = await loadCircuits(circuits);
3816
} catch (err) {
39-
response.error = err;
17+
logger.error('Error in load-circuits', err);
18+
response.error = 'Load-circuits failed';
4019
}
4120

4221
rabbitmq.sendMessage(replyTo, response, { correlationId });

src/routes/generateKeys.mjs

Lines changed: 3 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,14 @@
11
import express from 'express';
2-
import fs from 'fs';
3-
import path from 'path';
4-
import zokrates from '@eyblockchain/zokrates-zexe.js';
5-
import logger from '../utils/logger.mjs';
2+
import generateKeys from '../services/generateKeys.mjs';
63

74
const router = express.Router();
85

9-
const outputPath = `./output`;
10-
const circuitsPath = `./circuits`;
11-
126
router.post('/', async (req, res, next) => {
137
req.setTimeout(3600000); // 1 hour
14-
const { filepath, curve = 'bls12_377', backend = 'zexe', provingScheme = 'gm17' } = req.body;
158
try {
16-
const ext = path.extname(filepath);
17-
const circuitName = path.basename(filepath, '.zok'); // filename without '.zok'
18-
const circuitDir = filepath.replace(ext, '');
19-
20-
fs.mkdirSync(`${outputPath}/${circuitDir}`, { recursive: true });
21-
22-
logger.info('Compile...');
23-
await zokrates.compile(
24-
`${circuitsPath}/${filepath}`,
25-
`${outputPath}/${circuitDir}`,
26-
`${circuitName}_out`,
27-
curve,
28-
);
29-
30-
logger.info('Setup...');
31-
await zokrates.setup(
32-
`${outputPath}/${circuitDir}/${circuitName}_out`,
33-
`${outputPath}/${circuitDir}`,
34-
provingScheme,
35-
backend,
36-
`${circuitName}_vk`,
37-
`${circuitName}_pk`,
38-
);
39-
40-
const vk = await zokrates.extractVk(`${outputPath}/${circuitDir}/${circuitName}_vk.key`);
41-
42-
logger.info(`Complete`);
43-
44-
return res.send({ vk });
9+
res.send(await generateKeys(req.body));
4510
} catch (err) {
46-
return next(err);
11+
next(err);
4712
}
4813
});
4914

src/routes/generateProof.mjs

Lines changed: 3 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,16 @@
11
import fs from 'fs';
2-
import util from 'util';
32
import express from 'express';
4-
import zokrates from '@eyblockchain/zokrates-zexe.js';
5-
import path from 'path';
6-
import { getProofByCircuitPath } from '../utils/filing.mjs';
7-
import logger from '../utils/logger.mjs';
8-
9-
const unlink = util.promisify(fs.unlink);
3+
import generateProof from '../services/generateProof.mjs';
104

115
const router = express.Router();
126

13-
const outputPath = `./output`;
14-
157
router.post('/', async (req, res, next) => {
168
req.setTimeout(3600000); // 1 hour
17-
const {
18-
folderpath,
19-
inputs,
20-
transactionInputs,
21-
outputDirectoryPath,
22-
proofFileName,
23-
backend = 'zexe',
24-
provingScheme = 'gm17',
25-
} = req.body;
26-
logger.info(`Received request to /generate-proof`);
27-
logger.debug(JSON.stringify(req.body, null, 2));
28-
29-
const circuitName = path.basename(folderpath);
30-
31-
// Delete previous witness/proof files if they exist.
32-
// Prevents bad inputs from going through anyway.
33-
try {
34-
await unlink(`${outputPath}/${folderpath}/${circuitName}_witness`);
35-
await unlink(`${outputPath}/${folderpath}/${circuitName}_proof.json`);
36-
} catch {
37-
// Do nothing. It's okay if files don't exist.
38-
}
39-
40-
const opts = {};
41-
opts.createFile = true;
42-
opts.directory = `./output/${folderpath}` || outputDirectoryPath;
43-
opts.fileName = `${circuitName}_proof.json` || proofFileName;
449

4510
try {
46-
logger.info('Compute witness...');
47-
await zokrates.computeWitness(
48-
`${outputPath}/${folderpath}/${circuitName}_out`,
49-
`${outputPath}/${folderpath}/`,
50-
`${circuitName}_witness`,
51-
inputs,
52-
);
53-
54-
logger.info('Generate proof...');
55-
await zokrates.generateProof(
56-
`${outputPath}/${folderpath}/${circuitName}_pk.key`,
57-
`${outputPath}/${folderpath}/${circuitName}_out`,
58-
`${outputPath}/${folderpath}/${circuitName}_witness`,
59-
provingScheme,
60-
backend,
61-
opts,
62-
);
63-
64-
const { proof, inputs: publicInputs } = await getProofByCircuitPath(folderpath);
65-
66-
logger.info(`Complete`);
67-
logger.debug(`Responding with proof and inputs:`);
68-
logger.debug(JSON.stringify(req.body, null, 2));
69-
logger.debug(publicInputs);
70-
return res.send({
71-
proof,
72-
inputs: publicInputs,
73-
type: folderpath,
74-
transactionInputs,
75-
});
11+
res.send(await generateProof(req.body));
7612
} catch (err) {
77-
return next(err);
13+
next(err);
7814
}
7915
});
8016

0 commit comments

Comments
 (0)