@devtion/backend 0.0.0-101d43f → 0.0.0-2ed8e18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/dist/src/functions/index.js +108 -90
- package/dist/src/functions/index.mjs +110 -92
- package/dist/types/functions/ceremony.d.ts.map +1 -1
- package/dist/types/functions/circuit.d.ts.map +1 -1
- package/dist/types/functions/storage.d.ts.map +1 -1
- package/dist/types/functions/timeout.d.ts.map +1 -1
- package/dist/types/functions/user.d.ts.map +1 -1
- package/dist/types/lib/errors.d.ts +1 -0
- package/dist/types/lib/errors.d.ts.map +1 -1
- package/dist/types/lib/utils.d.ts +1 -1
- package/dist/types/lib/utils.d.ts.map +1 -1
- package/dist/types/types/index.d.ts +1 -1
- package/dist/types/types/index.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/functions/ceremony.ts +8 -3
- package/src/functions/circuit.ts +119 -113
- package/src/functions/participant.ts +8 -8
- package/src/functions/storage.ts +5 -3
- package/src/functions/timeout.ts +3 -2
- package/src/functions/user.ts +17 -8
- package/src/lib/errors.ts +5 -0
- package/src/lib/utils.ts +3 -3
- package/src/types/index.ts +1 -1
package/README.md
CHANGED
|
@@ -102,10 +102,10 @@ yarn firebase:init
|
|
|
102
102
|
|
|
103
103
|
#### AWS Infrastructure
|
|
104
104
|
|
|
105
|
-
0. Login or create a [new AWS Account](https://portal.aws.amazon.com/billing/signup?nc2=h_ct&src=header_signup&redirect_url=https%3A%2F%2Faws.amazon.com%2Fregistration-confirmation#/start/email).
|
|
105
|
+
0. Login or create a [new AWS Account](https://portal.aws.amazon.com/billing/signup?nc2=h_ct&src=header_signup&redirect_url=https%3A%2F%2Faws.amazon.com%2Fregistration-confirmation#/start/email).
|
|
106
106
|
- The AWS free tier account will cover a good number of requests for ceremonies but there could be some costs based on your ceremony circuits size.
|
|
107
|
-
1. Create an access key for a user with Admin privileges (
|
|
108
|
-
2. Setup the `awscli` ([docs](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html)) and add the keys for this user.
|
|
107
|
+
1. Create an access key for a user with Admin privileges (**NOT ROOT USER**)
|
|
108
|
+
2. Setup the `awscli` ([docs](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html)) and add the keys for this user.
|
|
109
109
|
3. Install `terraform` ([docs](https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli))
|
|
110
110
|
4. Decide on an AWS region (by default this is **us-east-1**) - if you want to change you will need to do the following:
|
|
111
111
|
1. update **aws/lambda/index.mjs** ([exact line](https://github.com/privacy-scaling-explorations/p0tion/blob/dev/packages/backend/aws/lambda/index.mjs#L3)) to the new region
|
|
@@ -117,9 +117,9 @@ yarn firebase:init
|
|
|
117
117
|
1. `terraform init`
|
|
118
118
|
2. `terraform plan`
|
|
119
119
|
3. `terraform apply`
|
|
120
|
-
4. `terraform output secret_key`
|
|
120
|
+
4. `terraform output secret_key`
|
|
121
121
|
- To print the secret access key for the IAM user
|
|
122
|
-
|
|
122
|
+
5. Store the other values (sns_topic_arn etc.)
|
|
123
123
|
- These will be needed for the .env file configuration
|
|
124
124
|
|
|
125
125
|
The IAM user created with the steps above can be used for all p0tion's features.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @module @
|
|
3
|
-
* @version 1.0.
|
|
2
|
+
* @module @devtion/backend
|
|
3
|
+
* @version 1.0.9
|
|
4
4
|
* @file MPC Phase 2 backend for Firebase services management
|
|
5
5
|
* @copyright Ethereum Foundation 2022
|
|
6
6
|
* @license MIT
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
var admin = require('firebase-admin');
|
|
12
12
|
var functions = require('firebase-functions');
|
|
13
13
|
var dotenv = require('dotenv');
|
|
14
|
-
var actions = require('@
|
|
14
|
+
var actions = require('@devtion/actions');
|
|
15
15
|
var htmlEntities = require('html-entities');
|
|
16
16
|
var firestore = require('firebase-admin/firestore');
|
|
17
17
|
var clientS3 = require('@aws-sdk/client-s3');
|
|
@@ -144,7 +144,8 @@ const SPECIFIC_ERRORS = {
|
|
|
144
144
|
SE_VM_FAILED_COMMAND_EXECUTION: makeError("failed-precondition", "VM command execution failed", "Please, contact the coordinator if this error persists."),
|
|
145
145
|
SE_VM_TIMEDOUT_COMMAND_EXECUTION: makeError("deadline-exceeded", "VM command execution took too long and has been timed-out", "Please, contact the coordinator if this error persists."),
|
|
146
146
|
SE_VM_CANCELLED_COMMAND_EXECUTION: makeError("cancelled", "VM command execution has been cancelled", "Please, contact the coordinator if this error persists."),
|
|
147
|
-
SE_VM_DELAYED_COMMAND_EXECUTION: makeError("unavailable", "VM command execution has been delayed since there were no available instance at the moment", "Please, contact the coordinator if this error persists.")
|
|
147
|
+
SE_VM_DELAYED_COMMAND_EXECUTION: makeError("unavailable", "VM command execution has been delayed since there were no available instance at the moment", "Please, contact the coordinator if this error persists."),
|
|
148
|
+
SE_VM_UNKNOWN_COMMAND_STATUS: makeError("unavailable", "VM command execution has failed due to an unknown status code", "Please, contact the coordinator if this error persists.")
|
|
148
149
|
};
|
|
149
150
|
/**
|
|
150
151
|
* A set of common errors.
|
|
@@ -328,7 +329,7 @@ const downloadArtifactFromS3Bucket = async (bucketName, objectKey, localFilePath
|
|
|
328
329
|
const writeStream = node_fs.createWriteStream(localFilePath);
|
|
329
330
|
const streamPipeline = node_util.promisify(node_stream.pipeline);
|
|
330
331
|
await streamPipeline(response.body, writeStream);
|
|
331
|
-
writeStream.on(
|
|
332
|
+
writeStream.on("finish", () => {
|
|
332
333
|
writeStream.end();
|
|
333
334
|
});
|
|
334
335
|
};
|
|
@@ -562,7 +563,9 @@ const registerAuthUser = functions__namespace
|
|
|
562
563
|
// Delete user
|
|
563
564
|
await auth.deleteUser(user.uid);
|
|
564
565
|
// Throw error
|
|
565
|
-
logAndThrowError(makeError("permission-denied", "The user is not allowed to sign up because their Github reputation is not high enough.", `The user ${user.displayName === "Null" || user.displayName === null
|
|
566
|
+
logAndThrowError(makeError("permission-denied", "The user is not allowed to sign up because their Github reputation is not high enough.", `The user ${user.displayName === "Null" || user.displayName === null
|
|
567
|
+
? user.uid
|
|
568
|
+
: user.displayName} is not allowed to sign up because their Github reputation is not high enough. Please contact the administrator if you think this is a mistake.`));
|
|
566
569
|
}
|
|
567
570
|
// store locally
|
|
568
571
|
avatarUrl = avatarURL;
|
|
@@ -577,7 +580,7 @@ const registerAuthUser = functions__namespace
|
|
|
577
580
|
}
|
|
578
581
|
// Set document (nb. we refer to providerData[0] because we use Github OAuth provider only).
|
|
579
582
|
// In future releases we might want to loop through the providerData array as we support
|
|
580
|
-
// more providers.
|
|
583
|
+
// more providers.
|
|
581
584
|
await userRef.set({
|
|
582
585
|
name: encodedDisplayName,
|
|
583
586
|
encodedDisplayName,
|
|
@@ -593,7 +596,7 @@ const registerAuthUser = functions__namespace
|
|
|
593
596
|
// we want to create a new collection for the users to store the avatars
|
|
594
597
|
const avatarRef = firestore.collection(actions.commonTerms.collections.avatars.name).doc(uid);
|
|
595
598
|
await avatarRef.set({
|
|
596
|
-
avatarUrl: avatarUrl || ""
|
|
599
|
+
avatarUrl: avatarUrl || ""
|
|
597
600
|
});
|
|
598
601
|
printLog(`Authenticated user document with identifier ${uid} has been correctly stored`, LogLevel.DEBUG);
|
|
599
602
|
printLog(`Authenticated user avatar with identifier ${uid} has been correctly stored`, LogLevel.DEBUG);
|
|
@@ -733,7 +736,7 @@ const setupCeremony = functions__namespace
|
|
|
733
736
|
// Check if using the VM approach for contribution verification.
|
|
734
737
|
if (circuit.verification.cfOrVm === "VM" /* CircuitContributionVerificationMechanism.VM */) {
|
|
735
738
|
// VM command to be run at the startup.
|
|
736
|
-
const startupCommand = actions.vmBootstrapCommand(bucketName);
|
|
739
|
+
const startupCommand = actions.vmBootstrapCommand(`${bucketName}/circuits/${circuit.name}`);
|
|
737
740
|
// Get EC2 client.
|
|
738
741
|
const ec2Client = await createEC2Client();
|
|
739
742
|
// Get AWS variables.
|
|
@@ -742,7 +745,8 @@ const setupCeremony = functions__namespace
|
|
|
742
745
|
const vmCommands = actions.vmDependenciesAndCacheArtifactsCommand(`${bucketName}/${circuit.files?.initialZkeyStoragePath}`, `${bucketName}/${circuit.files?.potStoragePath}`, snsTopic, region);
|
|
743
746
|
printLog(`Check VM dependencies and cache artifacts commands ${vmCommands.join("\n")}`, LogLevel.DEBUG);
|
|
744
747
|
// Upload the post-startup commands script file.
|
|
745
|
-
|
|
748
|
+
printLog(`Uploading VM post-startup commands script file ${actions.vmBootstrapScriptFilename}`, LogLevel.DEBUG);
|
|
749
|
+
await uploadFileToBucketNoFile(bucketName, `circuits/${circuit.name}/${actions.vmBootstrapScriptFilename}`, vmCommands.join("\n"));
|
|
746
750
|
// Compute the VM disk space requirement (in GB).
|
|
747
751
|
const vmDiskSize = actions.computeDiskSizeForVM(circuit.zKeySizeInBytes, circuit.metadata?.pot);
|
|
748
752
|
printLog(`Check VM startup commands ${startupCommand.join("\n")}`, LogLevel.DEBUG);
|
|
@@ -889,7 +893,7 @@ dotenv.config();
|
|
|
889
893
|
* @dev true when the participant can participate (1.A, 3.B, 1.D); otherwise false.
|
|
890
894
|
*/
|
|
891
895
|
const checkParticipantForCeremony = functions__namespace
|
|
892
|
-
.region(
|
|
896
|
+
.region("europe-west1")
|
|
893
897
|
.runWith({
|
|
894
898
|
memory: "512MB"
|
|
895
899
|
})
|
|
@@ -993,7 +997,7 @@ const checkParticipantForCeremony = functions__namespace
|
|
|
993
997
|
* 2) the participant has just finished the contribution for a circuit (contributionProgress != 0 && status = CONTRIBUTED && contributionStep = COMPLETED).
|
|
994
998
|
*/
|
|
995
999
|
const progressToNextCircuitForContribution = functions__namespace
|
|
996
|
-
.region(
|
|
1000
|
+
.region("europe-west1")
|
|
997
1001
|
.runWith({
|
|
998
1002
|
memory: "512MB"
|
|
999
1003
|
})
|
|
@@ -1040,7 +1044,7 @@ const progressToNextCircuitForContribution = functions__namespace
|
|
|
1040
1044
|
* 5) Completed contribution computation and verification.
|
|
1041
1045
|
*/
|
|
1042
1046
|
const progressToNextContributionStep = functions__namespace
|
|
1043
|
-
.region(
|
|
1047
|
+
.region("europe-west1")
|
|
1044
1048
|
.runWith({
|
|
1045
1049
|
memory: "512MB"
|
|
1046
1050
|
})
|
|
@@ -1091,7 +1095,7 @@ const progressToNextContributionStep = functions__namespace
|
|
|
1091
1095
|
* @dev enable the current contributor to resume a contribution from where it had left off.
|
|
1092
1096
|
*/
|
|
1093
1097
|
const permanentlyStoreCurrentContributionTimeAndHash = functions__namespace
|
|
1094
|
-
.region(
|
|
1098
|
+
.region("europe-west1")
|
|
1095
1099
|
.runWith({
|
|
1096
1100
|
memory: "512MB"
|
|
1097
1101
|
})
|
|
@@ -1133,7 +1137,7 @@ const permanentlyStoreCurrentContributionTimeAndHash = functions__namespace
|
|
|
1133
1137
|
* @dev enable the current contributor to resume a multi-part upload from where it had left off.
|
|
1134
1138
|
*/
|
|
1135
1139
|
const temporaryStoreCurrentContributionMultiPartUploadId = functions__namespace
|
|
1136
|
-
.region(
|
|
1140
|
+
.region("europe-west1")
|
|
1137
1141
|
.runWith({
|
|
1138
1142
|
memory: "512MB"
|
|
1139
1143
|
})
|
|
@@ -1171,7 +1175,7 @@ const temporaryStoreCurrentContributionMultiPartUploadId = functions__namespace
|
|
|
1171
1175
|
* @dev enable the current contributor to resume a multi-part upload from where it had left off.
|
|
1172
1176
|
*/
|
|
1173
1177
|
const temporaryStoreCurrentContributionUploadedChunkData = functions__namespace
|
|
1174
|
-
.region(
|
|
1178
|
+
.region("europe-west1")
|
|
1175
1179
|
.runWith({
|
|
1176
1180
|
memory: "512MB"
|
|
1177
1181
|
})
|
|
@@ -1213,7 +1217,7 @@ const temporaryStoreCurrentContributionUploadedChunkData = functions__namespace
|
|
|
1213
1217
|
* contributed to every selected ceremony circuits (= DONE).
|
|
1214
1218
|
*/
|
|
1215
1219
|
const checkAndPrepareCoordinatorForFinalization = functions__namespace
|
|
1216
|
-
.region(
|
|
1220
|
+
.region("europe-west1")
|
|
1217
1221
|
.runWith({
|
|
1218
1222
|
memory: "512MB"
|
|
1219
1223
|
})
|
|
@@ -1365,39 +1369,54 @@ const coordinate = async (participant, circuit, isSingleParticipantCoordination,
|
|
|
1365
1369
|
* Wait until the command has completed its execution inside the VM.
|
|
1366
1370
|
* @dev this method implements a custom interval to check 5 times after 1 minute if the command execution
|
|
1367
1371
|
* has been completed or not by calling the `retrieveCommandStatus` method.
|
|
1368
|
-
* @param {any} resolve the promise.
|
|
1369
|
-
* @param {any} reject the promise.
|
|
1370
1372
|
* @param {SSMClient} ssm the SSM client.
|
|
1371
1373
|
* @param {string} vmInstanceId the unique identifier of the VM instance.
|
|
1372
1374
|
* @param {string} commandId the unique identifier of the VM command.
|
|
1373
1375
|
* @returns <Promise<void>> true when the command execution succeed; otherwise false.
|
|
1374
1376
|
*/
|
|
1375
|
-
const waitForVMCommandExecution = (
|
|
1376
|
-
const
|
|
1377
|
+
const waitForVMCommandExecution = (ssm, vmInstanceId, commandId) => new Promise((resolve, reject) => {
|
|
1378
|
+
const poll = async () => {
|
|
1377
1379
|
try {
|
|
1378
1380
|
// Get command status.
|
|
1379
1381
|
const cmdStatus = await actions.retrieveCommandStatus(ssm, vmInstanceId, commandId);
|
|
1380
1382
|
printLog(`Checking command ${commandId} status => ${cmdStatus}`, LogLevel.DEBUG);
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1383
|
+
let error;
|
|
1384
|
+
switch (cmdStatus) {
|
|
1385
|
+
case clientSsm.CommandInvocationStatus.CANCELLING:
|
|
1386
|
+
case clientSsm.CommandInvocationStatus.CANCELLED: {
|
|
1387
|
+
error = SPECIFIC_ERRORS.SE_VM_CANCELLED_COMMAND_EXECUTION;
|
|
1388
|
+
break;
|
|
1389
|
+
}
|
|
1390
|
+
case clientSsm.CommandInvocationStatus.DELAYED: {
|
|
1391
|
+
error = SPECIFIC_ERRORS.SE_VM_DELAYED_COMMAND_EXECUTION;
|
|
1392
|
+
break;
|
|
1393
|
+
}
|
|
1394
|
+
case clientSsm.CommandInvocationStatus.FAILED: {
|
|
1395
|
+
error = SPECIFIC_ERRORS.SE_VM_FAILED_COMMAND_EXECUTION;
|
|
1396
|
+
break;
|
|
1397
|
+
}
|
|
1398
|
+
case clientSsm.CommandInvocationStatus.TIMED_OUT: {
|
|
1399
|
+
error = SPECIFIC_ERRORS.SE_VM_TIMEDOUT_COMMAND_EXECUTION;
|
|
1400
|
+
break;
|
|
1401
|
+
}
|
|
1402
|
+
case clientSsm.CommandInvocationStatus.IN_PROGRESS:
|
|
1403
|
+
case clientSsm.CommandInvocationStatus.PENDING: {
|
|
1404
|
+
// wait a minute and poll again
|
|
1405
|
+
setTimeout(poll, 60000);
|
|
1406
|
+
return;
|
|
1407
|
+
}
|
|
1408
|
+
case clientSsm.CommandInvocationStatus.SUCCESS: {
|
|
1409
|
+
printLog(`Command ${commandId} successfully completed`, LogLevel.DEBUG);
|
|
1410
|
+
// Resolve the promise.
|
|
1411
|
+
resolve();
|
|
1412
|
+
return;
|
|
1413
|
+
}
|
|
1414
|
+
default: {
|
|
1415
|
+
logAndThrowError(SPECIFIC_ERRORS.SE_VM_UNKNOWN_COMMAND_STATUS);
|
|
1416
|
+
}
|
|
1397
1417
|
}
|
|
1398
|
-
|
|
1399
|
-
logAndThrowError(
|
|
1400
|
-
reject();
|
|
1418
|
+
if (error) {
|
|
1419
|
+
logAndThrowError(error);
|
|
1401
1420
|
}
|
|
1402
1421
|
}
|
|
1403
1422
|
catch (error) {
|
|
@@ -1407,12 +1426,9 @@ const waitForVMCommandExecution = (resolve, reject, ssm, vmInstanceId, commandId
|
|
|
1407
1426
|
// Reject the promise.
|
|
1408
1427
|
reject();
|
|
1409
1428
|
}
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
}
|
|
1414
|
-
}, 60000); // 1 minute.
|
|
1415
|
-
};
|
|
1429
|
+
};
|
|
1430
|
+
setTimeout(poll, 60000);
|
|
1431
|
+
});
|
|
1416
1432
|
/**
|
|
1417
1433
|
* This method is used to coordinate the waiting queues of ceremony circuits.
|
|
1418
1434
|
* @dev this cloud function is triggered whenever an update of a document related to a participant of a ceremony occurs.
|
|
@@ -1433,7 +1449,7 @@ const waitForVMCommandExecution = (resolve, reject, ssm, vmInstanceId, commandId
|
|
|
1433
1449
|
* - Just completed a contribution or all contributions for each circuit. If yes, coordinate (multi-participant scenario).
|
|
1434
1450
|
*/
|
|
1435
1451
|
const coordinateCeremonyParticipant = functionsV1__namespace
|
|
1436
|
-
.region(
|
|
1452
|
+
.region("europe-west1")
|
|
1437
1453
|
.runWith({
|
|
1438
1454
|
memory: "512MB"
|
|
1439
1455
|
})
|
|
@@ -1536,7 +1552,7 @@ const checkIfVMRunning = async (ec2, vmInstanceId, attempts = 5) => {
|
|
|
1536
1552
|
* 1.A.4.C.1) If true, update circuit waiting for queue and average timings accordingly to contribution verification results;
|
|
1537
1553
|
* 2) Send all updates atomically to the Firestore database.
|
|
1538
1554
|
*/
|
|
1539
|
-
const verifycontribution = functionsV2__namespace.https.onCall({ memory: "16GiB", timeoutSeconds: 3600, region:
|
|
1555
|
+
const verifycontribution = functionsV2__namespace.https.onCall({ memory: "16GiB", timeoutSeconds: 3600, region: "europe-west1" }, async (request) => {
|
|
1540
1556
|
if (!request.auth || (!request.auth.token.participant && !request.auth.token.coordinator))
|
|
1541
1557
|
logAndThrowError(SPECIFIC_ERRORS.SE_AUTH_NO_CURRENT_AUTH_USER);
|
|
1542
1558
|
if (!request.data.ceremonyId ||
|
|
@@ -1647,8 +1663,6 @@ const verifycontribution = functionsV2__namespace.https.onCall({ memory: "16GiB"
|
|
|
1647
1663
|
lastZkeyBlake2bHash = match.at(0);
|
|
1648
1664
|
// re upload the formatted verification transcript
|
|
1649
1665
|
await uploadFileToBucket(bucketName, verificationTranscriptStoragePathAndFilename, verificationTranscriptTemporaryLocalPath, true);
|
|
1650
|
-
// Stop VM instance.
|
|
1651
|
-
await actions.stopEC2Instance(ec2, vmInstanceId);
|
|
1652
1666
|
}
|
|
1653
1667
|
else {
|
|
1654
1668
|
// Upload verification transcript.
|
|
@@ -1709,6 +1723,9 @@ const verifycontribution = functionsV2__namespace.https.onCall({ memory: "16GiB"
|
|
|
1709
1723
|
lastUpdated: getCurrentServerTimestampInMillis()
|
|
1710
1724
|
});
|
|
1711
1725
|
}
|
|
1726
|
+
// Stop VM instance
|
|
1727
|
+
if (isUsingVM)
|
|
1728
|
+
await actions.stopEC2Instance(ec2, vmInstanceId);
|
|
1712
1729
|
// Step (1.A.4.C)
|
|
1713
1730
|
if (!isFinalizing) {
|
|
1714
1731
|
// Step (1.A.4.C.1)
|
|
@@ -1723,7 +1740,7 @@ const verifycontribution = functionsV2__namespace.https.onCall({ memory: "16GiB"
|
|
|
1723
1740
|
const newAvgVerifyCloudFunctionTime = avgVerifyCloudFunctionTime > 0
|
|
1724
1741
|
? (avgVerifyCloudFunctionTime + verifyCloudFunctionTime) / 2
|
|
1725
1742
|
: verifyCloudFunctionTime;
|
|
1726
|
-
// Prepare tx to update circuit average contribution/verification time.
|
|
1743
|
+
// Prepare tx to update circuit average contribution/verification time.
|
|
1727
1744
|
const updatedCircuitDoc = await getDocumentById(actions.getCircuitsCollectionPath(ceremonyId), circuitId);
|
|
1728
1745
|
const { waitingQueue: updatedWaitingQueue } = updatedCircuitDoc.data();
|
|
1729
1746
|
/// @dev this must happen only for valid contributions.
|
|
@@ -1773,7 +1790,7 @@ const verifycontribution = functionsV2__namespace.https.onCall({ memory: "16GiB"
|
|
|
1773
1790
|
commandId = await actions.runCommandUsingSSM(ssm, vmInstanceId, verificationCommand);
|
|
1774
1791
|
printLog(`Starting the execution of command ${commandId}`, LogLevel.DEBUG);
|
|
1775
1792
|
// Step (1.A.3.3).
|
|
1776
|
-
return
|
|
1793
|
+
return waitForVMCommandExecution(ssm, vmInstanceId, commandId)
|
|
1777
1794
|
.then(async () => {
|
|
1778
1795
|
// Command execution successfully completed.
|
|
1779
1796
|
printLog(`Command ${commandId} execution has been successfully completed`, LogLevel.DEBUG);
|
|
@@ -1785,40 +1802,38 @@ const verifycontribution = functionsV2__namespace.https.onCall({ memory: "16GiB"
|
|
|
1785
1802
|
logAndThrowError(COMMON_ERRORS.CM_INVALID_COMMAND_EXECUTION);
|
|
1786
1803
|
});
|
|
1787
1804
|
}
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
printLog(`Error while unlinking temporary files - Error ${error}`, LogLevel.WARN);
|
|
1819
|
-
}
|
|
1820
|
-
await completeVerification();
|
|
1805
|
+
// CF approach.
|
|
1806
|
+
printLog(`CF mechanism`, LogLevel.DEBUG);
|
|
1807
|
+
const potStoragePath = actions.getPotStorageFilePath(files.potFilename);
|
|
1808
|
+
const firstZkeyStoragePath = actions.getZkeyStorageFilePath(prefix, `${prefix}_${actions.genesisZkeyIndex}.zkey`);
|
|
1809
|
+
// Prepare temporary file paths.
|
|
1810
|
+
// (nb. these are needed to download the necessary artifacts for verification from AWS S3).
|
|
1811
|
+
verificationTranscriptTemporaryLocalPath = createTemporaryLocalPath(verificationTranscriptCompleteFilename);
|
|
1812
|
+
const potTempFilePath = createTemporaryLocalPath(`${circuitId}_${participantDoc.id}.pot`);
|
|
1813
|
+
const firstZkeyTempFilePath = createTemporaryLocalPath(`${circuitId}_${participantDoc.id}_genesis.zkey`);
|
|
1814
|
+
const lastZkeyTempFilePath = createTemporaryLocalPath(`${circuitId}_${participantDoc.id}_last.zkey`);
|
|
1815
|
+
// Create and populate transcript.
|
|
1816
|
+
const transcriptLogger = actions.createCustomLoggerForFile(verificationTranscriptTemporaryLocalPath);
|
|
1817
|
+
transcriptLogger.info(`${isFinalizing ? `Final verification` : `Verification`} transcript for ${prefix} circuit Phase 2 contribution.\n${isFinalizing ? `Coordinator ` : `Contributor # ${Number(lastZkeyIndex)}`} (${contributorOrCoordinatorIdentifier})\n`);
|
|
1818
|
+
// Step (1.A.2).
|
|
1819
|
+
await downloadArtifactFromS3Bucket(bucketName, potStoragePath, potTempFilePath);
|
|
1820
|
+
await downloadArtifactFromS3Bucket(bucketName, firstZkeyStoragePath, firstZkeyTempFilePath);
|
|
1821
|
+
await downloadArtifactFromS3Bucket(bucketName, lastZkeyStoragePath, lastZkeyTempFilePath);
|
|
1822
|
+
// Step (1.A.4).
|
|
1823
|
+
isContributionValid = await snarkjs.zKey.verifyFromInit(firstZkeyTempFilePath, potTempFilePath, lastZkeyTempFilePath, transcriptLogger);
|
|
1824
|
+
// Compute contribution hash.
|
|
1825
|
+
lastZkeyBlake2bHash = await actions.blake512FromPath(lastZkeyTempFilePath);
|
|
1826
|
+
// Free resources by unlinking temporary folders.
|
|
1827
|
+
// Do not free-up verification transcript path here.
|
|
1828
|
+
try {
|
|
1829
|
+
fs.unlinkSync(potTempFilePath);
|
|
1830
|
+
fs.unlinkSync(firstZkeyTempFilePath);
|
|
1831
|
+
fs.unlinkSync(lastZkeyTempFilePath);
|
|
1832
|
+
}
|
|
1833
|
+
catch (error) {
|
|
1834
|
+
printLog(`Error while unlinking temporary files - Error ${error}`, LogLevel.WARN);
|
|
1821
1835
|
}
|
|
1836
|
+
await completeVerification();
|
|
1822
1837
|
}
|
|
1823
1838
|
});
|
|
1824
1839
|
/**
|
|
@@ -1827,7 +1842,7 @@ const verifycontribution = functionsV2__namespace.https.onCall({ memory: "16GiB"
|
|
|
1827
1842
|
* this does not happen if the participant is actually the coordinator who is finalizing the ceremony.
|
|
1828
1843
|
*/
|
|
1829
1844
|
const refreshParticipantAfterContributionVerification = functionsV1__namespace
|
|
1830
|
-
.region(
|
|
1845
|
+
.region("europe-west1")
|
|
1831
1846
|
.runWith({
|
|
1832
1847
|
memory: "512MB"
|
|
1833
1848
|
})
|
|
@@ -1888,7 +1903,7 @@ const refreshParticipantAfterContributionVerification = functionsV1__namespace
|
|
|
1888
1903
|
* and verification key extracted from the circuit final contribution (as part of the ceremony finalization process).
|
|
1889
1904
|
*/
|
|
1890
1905
|
const finalizeCircuit = functionsV1__namespace
|
|
1891
|
-
.region(
|
|
1906
|
+
.region("europe-west1")
|
|
1892
1907
|
.runWith({
|
|
1893
1908
|
memory: "512MB"
|
|
1894
1909
|
})
|
|
@@ -2085,8 +2100,10 @@ const createBucket = functions__namespace
|
|
|
2085
2100
|
CORSConfiguration: {
|
|
2086
2101
|
CORSRules: [
|
|
2087
2102
|
{
|
|
2088
|
-
AllowedMethods: ["GET"],
|
|
2089
|
-
AllowedOrigins: ["*"]
|
|
2103
|
+
AllowedMethods: ["GET", "PUT"],
|
|
2104
|
+
AllowedOrigins: ["*"],
|
|
2105
|
+
ExposeHeaders: ["ETag", "Content-Length"],
|
|
2106
|
+
AllowedHeaders: ["*"]
|
|
2090
2107
|
}
|
|
2091
2108
|
]
|
|
2092
2109
|
}
|
|
@@ -2563,7 +2580,8 @@ const resumeContributionAfterTimeoutExpiration = functions__namespace
|
|
|
2563
2580
|
if (status === "EXHUMED" /* ParticipantStatus.EXHUMED */)
|
|
2564
2581
|
await participantDoc.ref.update({
|
|
2565
2582
|
status: "READY" /* ParticipantStatus.READY */,
|
|
2566
|
-
lastUpdated: getCurrentServerTimestampInMillis()
|
|
2583
|
+
lastUpdated: getCurrentServerTimestampInMillis(),
|
|
2584
|
+
tempContributionData: {}
|
|
2567
2585
|
});
|
|
2568
2586
|
else
|
|
2569
2587
|
logAndThrowError(SPECIFIC_ERRORS.SE_CONTRIBUTE_CANNOT_PROGRESS_TO_NEXT_CIRCUIT);
|