@devtion/backend 0.0.0-0fd4368 → 0.0.0-142ec0a
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 +28 -2
- package/dist/src/functions/index.js +157 -165
- package/dist/src/functions/index.mjs +157 -165
- 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/package.json +3 -3
- package/src/functions/ceremony.ts +9 -4
- package/src/functions/circuit.ts +137 -185
- package/src/functions/participant.ts +9 -9
- package/src/functions/storage.ts +7 -4
- package/src/functions/timeout.ts +5 -4
- package/src/functions/user.ts +33 -8
- package/src/lib/errors.ts +5 -0
- package/src/lib/utils.ts +11 -9
- package/src/types/index.ts +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timeout.d.ts","sourceRoot":"","sources":["../../../src/functions/timeout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,oBAAoB,CAAA;AAuB/C;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,iCAAiC,kCA6MxC,CAAA;AAEN;;;GAGG;AACH,eAAO,MAAM,wCAAwC,
|
|
1
|
+
{"version":3,"file":"timeout.d.ts","sourceRoot":"","sources":["../../../src/functions/timeout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,oBAAoB,CAAA;AAuB/C;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,iCAAiC,kCA6MxC,CAAA;AAEN;;;GAGG;AACH,eAAO,MAAM,wCAAwC,mDA0C/C,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../../src/functions/user.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,oBAAoB,CAAA;AAW/C;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,
|
|
1
|
+
{"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../../src/functions/user.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,oBAAoB,CAAA;AAW/C;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,mEAgHvB,CAAA;AACN;;;;GAIG;AACH,eAAO,MAAM,6BAA6B,mEA+BpC,CAAA"}
|
|
@@ -55,6 +55,7 @@ export declare const SPECIFIC_ERRORS: {
|
|
|
55
55
|
SE_VM_TIMEDOUT_COMMAND_EXECUTION: functions.auth.HttpsError;
|
|
56
56
|
SE_VM_CANCELLED_COMMAND_EXECUTION: functions.auth.HttpsError;
|
|
57
57
|
SE_VM_DELAYED_COMMAND_EXECUTION: functions.auth.HttpsError;
|
|
58
|
+
SE_VM_UNKNOWN_COMMAND_STATUS: functions.auth.HttpsError;
|
|
58
59
|
};
|
|
59
60
|
/**
|
|
60
61
|
* A set of common errors.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/lib/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AAC5E,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEzC;;;;;;;;GAQG;AACH,eAAO,MAAM,SAAS,cAAe,kBAAkB,WAAW,MAAM,YAAY,MAAM,KAAG,UAC9B,CAAA;AAE/D;;;;GAIG;AACH,eAAO,MAAM,QAAQ,YAAa,MAAM,YAAY,QAAQ,SAqB3D,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,gBAAgB,UAAW,UAAU,UAGjD,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/lib/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AAC5E,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEzC;;;;;;;;GAQG;AACH,eAAO,MAAM,SAAS,cAAe,kBAAkB,WAAW,MAAM,YAAY,MAAM,KAAG,UAC9B,CAAA;AAE/D;;;;GAIG;AACH,eAAO,MAAM,QAAQ,YAAa,MAAM,YAAY,QAAQ,SAqB3D,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,gBAAgB,UAAW,UAAU,UAGjD,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuI3B,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;CA2CzB,CAAA"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DocumentData, QuerySnapshot, DocumentSnapshot, QueryDocumentSnapshot, WhereFilterOp } from "firebase-admin/firestore";
|
|
2
2
|
import admin from "firebase-admin";
|
|
3
|
-
import { CircuitDocument } from "@
|
|
3
|
+
import { CircuitDocument } from "@devtion/actions";
|
|
4
4
|
import { SSMClient } from "@aws-sdk/client-ssm";
|
|
5
5
|
import { EC2Client } from "@aws-sdk/client-ec2";
|
|
6
6
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/lib/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,qBAAqB,EAErB,aAAa,EAChB,MAAM,0BAA0B,CAAA;AACjC,OAAO,KAAK,MAAM,gBAAgB,CAAA;AAWlC,OAAO,EAOH,eAAe,EAClB,MAAM,iBAAiB,CAAA;AAIxB,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAM/C;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,eACZ,MAAM,cACN,MAAM,KACnB,QAAQ,iBAAiB,YAAY,CAAC,CASxC,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,iCAAiC,QAAO,MAAoC,CAAA;AAEzF;;;GAGG;AACH,eAAO,MAAM,KAAK,OAAc,MAAM,KAAG,QAAQ,IAAI,CAAmB,CAAA;AAExE;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,eAAsB,MAAM,KAAG,QAAQ,MAAM,sBAAsB,YAAY,CAAC,CAAC,CAYhH,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,+BAA+B,eAC5B,MAAM,aACP,MAAM,KAClB,QAAQ,MAAM,sBAAsB,YAAY,CAAC,CAAC,CAUpD,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,eACpB,MAAM,iBACH,MAAM,KACtB,QAAQ,cAAc,YAAY,CAAC,CASrC,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,QAAa,QAAQ,MAAM,sBAAsB,YAAY,CAAC,CAAC,CAWhG,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,eACzB,MAAM,oBACA,MAAM,KACzB,QAAQ,sBAAsB,YAAY,CAAC,CAY7C,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,qBAAsB,MAAM,KAAG,MAAkD,CAAA;AAEtH;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,eAAsB,MAAM,aAAa,MAAM,iBAAiB,MAAM,kBA6B9G,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,eACf,MAAM,aACP,MAAM,iBACF,MAAM,aACX,OAAO,kBA4BpB,CAAA;AAED,eAAO,MAAM,wBAAwB,eACrB,MAAM,aACP,MAAM,QACX,MAAM,aACF,OAAO,kBAyBpB,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,YAAY,eAAsB,MAAM,aAAa,MAAM,kBAWvE,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,6BAA6B,UAC/B,MAAM,wBACS,OAAO,SACtB,aAAa,KACrB,QAAQ,MAAM,SAAS,cAAc,CAAC,MAAM,SAAS,aAAa,CAAC,CAYxD,CAAA;AAEd;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,eACjB,MAAM,aACP,MAAM,KAClB,QAAQ,sBAAsB,YAAY,CAAC,CAgB7C,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,oBAAqB,eAAe,KAAG,eAKvE,CAAA;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,QAAO,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/lib/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,qBAAqB,EAErB,aAAa,EAChB,MAAM,0BAA0B,CAAA;AACjC,OAAO,KAAK,MAAM,gBAAgB,CAAA;AAWlC,OAAO,EAOH,eAAe,EAClB,MAAM,iBAAiB,CAAA;AAIxB,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAM/C;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,eACZ,MAAM,cACN,MAAM,KACnB,QAAQ,iBAAiB,YAAY,CAAC,CASxC,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,iCAAiC,QAAO,MAAoC,CAAA;AAEzF;;;GAGG;AACH,eAAO,MAAM,KAAK,OAAc,MAAM,KAAG,QAAQ,IAAI,CAAmB,CAAA;AAExE;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,eAAsB,MAAM,KAAG,QAAQ,MAAM,sBAAsB,YAAY,CAAC,CAAC,CAYhH,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,+BAA+B,eAC5B,MAAM,aACP,MAAM,KAClB,QAAQ,MAAM,sBAAsB,YAAY,CAAC,CAAC,CAUpD,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,eACpB,MAAM,iBACH,MAAM,KACtB,QAAQ,cAAc,YAAY,CAAC,CASrC,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,QAAa,QAAQ,MAAM,sBAAsB,YAAY,CAAC,CAAC,CAWhG,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,eACzB,MAAM,oBACA,MAAM,KACzB,QAAQ,sBAAsB,YAAY,CAAC,CAY7C,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,qBAAsB,MAAM,KAAG,MAAkD,CAAA;AAEtH;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,eAAsB,MAAM,aAAa,MAAM,iBAAiB,MAAM,kBA6B9G,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,eACf,MAAM,aACP,MAAM,iBACF,MAAM,aACX,OAAO,kBA4BpB,CAAA;AAED,eAAO,MAAM,wBAAwB,eACrB,MAAM,aACP,MAAM,QACX,MAAM,aACF,OAAO,kBAyBpB,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,YAAY,eAAsB,MAAM,aAAa,MAAM,kBAWvE,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,6BAA6B,UAC/B,MAAM,wBACS,OAAO,SACtB,aAAa,KACrB,QAAQ,MAAM,SAAS,cAAc,CAAC,MAAM,SAAS,aAAa,CAAC,CAYxD,CAAA;AAEd;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,eACjB,MAAM,aACP,MAAM,KAClB,QAAQ,sBAAsB,YAAY,CAAC,CAgB7C,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,oBAAqB,eAAe,KAAG,eAKvE,CAAA;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,QAAO,GAerC,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,QAAO,GAkBlC,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,QAAa,QAAQ,SAAS,CAYzD,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,QAAa,QAAQ,SAAS,CAYzD,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,cAAqB,MAAM,KAAG,QAAQ,MAAM,CAQxE,CAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CeremonyInputData, CircuitDocument, ETagWithPartNumber } from "@
|
|
1
|
+
import { CeremonyInputData, CircuitDocument, ETagWithPartNumber } from "@devtion/actions";
|
|
2
2
|
/**
|
|
3
3
|
* Group all the necessary data needed for running the `setupCeremony` cloud function.
|
|
4
4
|
* @typedef {Object} SetupCeremonyData
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devtion/backend",
|
|
3
|
-
"version": "0.0.0-
|
|
3
|
+
"version": "0.0.0-142ec0a",
|
|
4
4
|
"description": "MPC Phase 2 backend for Firebase services management",
|
|
5
5
|
"repository": "git@github.com:privacy-scaling-explorations/p0tion.git",
|
|
6
6
|
"homepage": "https://github.com/privacy-scaling-explorations/p0tion",
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"@aws-sdk/client-ssm": "^3.357.0",
|
|
68
68
|
"@aws-sdk/middleware-endpoint": "^3.329.0",
|
|
69
69
|
"@aws-sdk/s3-request-presigner": "^3.329.0",
|
|
70
|
-
"@
|
|
70
|
+
"@devtion/actions": "latest",
|
|
71
71
|
"blakejs": "^1.2.1",
|
|
72
72
|
"dotenv": "^16.0.3",
|
|
73
73
|
"ethers": "5.7.2",
|
|
@@ -85,5 +85,5 @@
|
|
|
85
85
|
"publishConfig": {
|
|
86
86
|
"access": "public"
|
|
87
87
|
},
|
|
88
|
-
"gitHead": "
|
|
88
|
+
"gitHead": "e1031fbb36d4e2bbf1988f32fdc0ddfe230e8684"
|
|
89
89
|
}
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
vmBootstrapCommand,
|
|
19
19
|
vmDependenciesAndCacheArtifactsCommand,
|
|
20
20
|
vmBootstrapScriptFilename
|
|
21
|
-
} from "@
|
|
21
|
+
} from "@devtion/actions"
|
|
22
22
|
import { encode } from "html-entities"
|
|
23
23
|
import { SetupCeremonyData } from "../types/index"
|
|
24
24
|
import { COMMON_ERRORS, logAndThrowError, printLog, SPECIFIC_ERRORS } from "../lib/errors"
|
|
@@ -146,7 +146,7 @@ export const setupCeremony = functions
|
|
|
146
146
|
// Check if using the VM approach for contribution verification.
|
|
147
147
|
if (circuit.verification.cfOrVm === CircuitContributionVerificationMechanism.VM) {
|
|
148
148
|
// VM command to be run at the startup.
|
|
149
|
-
const startupCommand = vmBootstrapCommand(bucketName)
|
|
149
|
+
const startupCommand = vmBootstrapCommand(`${bucketName}/circuits/${circuit.name!}`)
|
|
150
150
|
|
|
151
151
|
// Get EC2 client.
|
|
152
152
|
const ec2Client = await createEC2Client()
|
|
@@ -165,7 +165,12 @@ export const setupCeremony = functions
|
|
|
165
165
|
printLog(`Check VM dependencies and cache artifacts commands ${vmCommands.join("\n")}`, LogLevel.DEBUG)
|
|
166
166
|
|
|
167
167
|
// Upload the post-startup commands script file.
|
|
168
|
-
|
|
168
|
+
printLog(`Uploading VM post-startup commands script file ${vmBootstrapScriptFilename}`, LogLevel.DEBUG)
|
|
169
|
+
await uploadFileToBucketNoFile(
|
|
170
|
+
bucketName,
|
|
171
|
+
`circuits/${circuit.name!}/${vmBootstrapScriptFilename}`,
|
|
172
|
+
vmCommands.join("\n")
|
|
173
|
+
)
|
|
169
174
|
|
|
170
175
|
// Compute the VM disk space requirement (in GB).
|
|
171
176
|
const vmDiskSize = computeDiskSizeForVM(circuit.zKeySizeInBytes!, circuit.metadata?.pot!)
|
|
@@ -293,7 +298,7 @@ export const finalizeCeremony = functions
|
|
|
293
298
|
const circuits = await getCeremonyCircuits(ceremonyId)
|
|
294
299
|
|
|
295
300
|
// Get final contribution for each circuit.
|
|
296
|
-
// nb. the `getFinalContributionDocument` checks the
|
|
301
|
+
// nb. the `getFinalContributionDocument` checks the existence of the final contribution document (if not present, throws).
|
|
297
302
|
// Therefore, we just need to call the method without taking any data to verify the pre-condition of having already computed
|
|
298
303
|
// the final contributions for each ceremony circuit.
|
|
299
304
|
for await (const circuit of circuits) await getFinalContribution(ceremonyId, circuit.id)
|
package/src/functions/circuit.ts
CHANGED
|
@@ -37,12 +37,14 @@ import {
|
|
|
37
37
|
createCustomLoggerForFile,
|
|
38
38
|
retrieveCommandStatus,
|
|
39
39
|
stopEC2Instance
|
|
40
|
-
} from "@
|
|
40
|
+
} from "@devtion/actions"
|
|
41
41
|
import { zKey } from "snarkjs"
|
|
42
42
|
import { CommandInvocationStatus, SSMClient } from "@aws-sdk/client-ssm"
|
|
43
|
+
import { EC2Client } from "@aws-sdk/client-ec2"
|
|
44
|
+
import { HttpsError } from "firebase-functions/v2/https"
|
|
43
45
|
import { FinalizeCircuitData, VerifyContributionData } from "../types/index"
|
|
44
46
|
import { LogLevel } from "../types/enums"
|
|
45
|
-
import { COMMON_ERRORS, logAndThrowError,
|
|
47
|
+
import { COMMON_ERRORS, logAndThrowError, printLog, SPECIFIC_ERRORS } from "../lib/errors"
|
|
46
48
|
import {
|
|
47
49
|
createEC2Client,
|
|
48
50
|
createSSMClient,
|
|
@@ -57,7 +59,6 @@ import {
|
|
|
57
59
|
sleep,
|
|
58
60
|
uploadFileToBucket
|
|
59
61
|
} from "../lib/utils"
|
|
60
|
-
import { EC2Client } from "@aws-sdk/client-ec2"
|
|
61
62
|
|
|
62
63
|
dotenv.config()
|
|
63
64
|
|
|
@@ -131,6 +132,7 @@ const coordinate = async (
|
|
|
131
132
|
|
|
132
133
|
newParticipantStatus = ParticipantStatus.CONTRIBUTING
|
|
133
134
|
newContributionStep = ParticipantContributionStep.DOWNLOADING
|
|
135
|
+
newCurrentContributorId = participant.id
|
|
134
136
|
}
|
|
135
137
|
// Scenario (B).
|
|
136
138
|
else if (participantIsNotCurrentContributor) {
|
|
@@ -213,113 +215,80 @@ const coordinate = async (
|
|
|
213
215
|
* Wait until the command has completed its execution inside the VM.
|
|
214
216
|
* @dev this method implements a custom interval to check 5 times after 1 minute if the command execution
|
|
215
217
|
* has been completed or not by calling the `retrieveCommandStatus` method.
|
|
216
|
-
* @param {any} resolve the promise.
|
|
217
|
-
* @param {any} reject the promise.
|
|
218
218
|
* @param {SSMClient} ssm the SSM client.
|
|
219
219
|
* @param {string} vmInstanceId the unique identifier of the VM instance.
|
|
220
220
|
* @param {string} commandId the unique identifier of the VM command.
|
|
221
221
|
* @returns <Promise<void>> true when the command execution succeed; otherwise false.
|
|
222
222
|
*/
|
|
223
|
-
const waitForVMCommandExecution = (
|
|
224
|
-
resolve
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
223
|
+
const waitForVMCommandExecution = (ssm: SSMClient, vmInstanceId: string, commandId: string): Promise<void> =>
|
|
224
|
+
new Promise((resolve, reject) => {
|
|
225
|
+
const poll = async () => {
|
|
226
|
+
try {
|
|
227
|
+
// Get command status.
|
|
228
|
+
const cmdStatus = await retrieveCommandStatus(ssm, vmInstanceId, commandId)
|
|
229
|
+
printLog(`Checking command ${commandId} status => ${cmdStatus}`, LogLevel.DEBUG)
|
|
230
|
+
|
|
231
|
+
let error: HttpsError | undefined
|
|
232
|
+
switch (cmdStatus) {
|
|
233
|
+
case CommandInvocationStatus.CANCELLING:
|
|
234
|
+
case CommandInvocationStatus.CANCELLED: {
|
|
235
|
+
error = SPECIFIC_ERRORS.SE_VM_CANCELLED_COMMAND_EXECUTION
|
|
236
|
+
break
|
|
237
|
+
}
|
|
238
|
+
case CommandInvocationStatus.DELAYED: {
|
|
239
|
+
error = SPECIFIC_ERRORS.SE_VM_DELAYED_COMMAND_EXECUTION
|
|
240
|
+
break
|
|
241
|
+
}
|
|
242
|
+
case CommandInvocationStatus.FAILED: {
|
|
243
|
+
error = SPECIFIC_ERRORS.SE_VM_FAILED_COMMAND_EXECUTION
|
|
244
|
+
break
|
|
245
|
+
}
|
|
246
|
+
case CommandInvocationStatus.TIMED_OUT: {
|
|
247
|
+
error = SPECIFIC_ERRORS.SE_VM_TIMEDOUT_COMMAND_EXECUTION
|
|
248
|
+
break
|
|
249
|
+
}
|
|
250
|
+
case CommandInvocationStatus.IN_PROGRESS:
|
|
251
|
+
case CommandInvocationStatus.PENDING: {
|
|
252
|
+
// wait a minute and poll again
|
|
253
|
+
setTimeout(poll, 60000)
|
|
254
|
+
return
|
|
255
|
+
}
|
|
256
|
+
case CommandInvocationStatus.SUCCESS: {
|
|
257
|
+
printLog(`Command ${commandId} successfully completed`, LogLevel.DEBUG)
|
|
258
|
+
|
|
259
|
+
// Resolve the promise.
|
|
260
|
+
resolve()
|
|
261
|
+
return
|
|
262
|
+
}
|
|
263
|
+
default: {
|
|
264
|
+
logAndThrowError(SPECIFIC_ERRORS.SE_VM_UNKNOWN_COMMAND_STATUS)
|
|
265
|
+
}
|
|
266
|
+
}
|
|
256
267
|
|
|
257
|
-
|
|
268
|
+
if (error) {
|
|
269
|
+
logAndThrowError(error)
|
|
270
|
+
}
|
|
271
|
+
} catch (error: any) {
|
|
272
|
+
printLog(`Invalid command ${commandId} execution`, LogLevel.DEBUG)
|
|
258
273
|
|
|
259
|
-
|
|
260
|
-
reject()
|
|
261
|
-
} finally {
|
|
262
|
-
// Clear the interval.
|
|
263
|
-
clearInterval(interval)
|
|
264
|
-
}
|
|
265
|
-
}, 60000) // 1 minute.
|
|
266
|
-
}
|
|
274
|
+
const ec2 = await createEC2Client()
|
|
267
275
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
const waitForFileDownload = (
|
|
277
|
-
resolve: any,
|
|
278
|
-
reject: any,
|
|
279
|
-
potTempFilePath: string,
|
|
280
|
-
firstZkeyTempFilePath: string,
|
|
281
|
-
lastZkeyTempFilePath: string,
|
|
282
|
-
circuitId: string,
|
|
283
|
-
participantId: string
|
|
284
|
-
) => {
|
|
285
|
-
const maxWaitTime = 5 * 60 * 1000 // 5 minutes
|
|
286
|
-
// every second check if the file download was completed
|
|
287
|
-
const interval = setInterval(async () => {
|
|
288
|
-
printLog(`Verifying that the artifacts were downloaded for circuit ${circuitId} and participant ${participantId}`, LogLevel.DEBUG)
|
|
289
|
-
try {
|
|
290
|
-
// check if files have been downloaded
|
|
291
|
-
if (!fs.existsSync(potTempFilePath)) {
|
|
292
|
-
printLog(`Pot file not found at ${potTempFilePath}`, LogLevel.DEBUG)
|
|
293
|
-
}
|
|
294
|
-
if (!fs.existsSync(firstZkeyTempFilePath)) {
|
|
295
|
-
printLog(`First zkey file not found at ${firstZkeyTempFilePath}`, LogLevel.DEBUG)
|
|
296
|
-
}
|
|
297
|
-
if (!fs.existsSync(lastZkeyTempFilePath)) {
|
|
298
|
-
printLog(`Last zkey file not found at ${lastZkeyTempFilePath}`, LogLevel.DEBUG)
|
|
299
|
-
}
|
|
276
|
+
// if it errors out, let's just log it as a warning so the coordinator is aware
|
|
277
|
+
try {
|
|
278
|
+
await stopEC2Instance(ec2, vmInstanceId)
|
|
279
|
+
} catch (error: any) {
|
|
280
|
+
printLog(`Error while stopping VM instance ${vmInstanceId} - Error ${error}`, LogLevel.WARN)
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
if (!error.toString().includes(commandId)) logAndThrowError(COMMON_ERRORS.CM_INVALID_COMMAND_EXECUTION)
|
|
300
284
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
printLog(`All required files are present on disk.`, LogLevel.INFO)
|
|
304
|
-
// resolve the promise
|
|
305
|
-
resolve()
|
|
285
|
+
// Reject the promise.
|
|
286
|
+
reject()
|
|
306
287
|
}
|
|
307
|
-
} catch (error: any) {
|
|
308
|
-
// if we have an error then we print it as a warning and reject
|
|
309
|
-
printLog(`Error while downloading files: ${error}`, LogLevel.WARN)
|
|
310
|
-
reject()
|
|
311
|
-
} finally {
|
|
312
|
-
printLog(`Clearing the interval for file download. Circuit ${circuitId} and participant ${participantId}`, LogLevel.DEBUG)
|
|
313
|
-
clearInterval(interval)
|
|
314
288
|
}
|
|
315
|
-
}, 5000)
|
|
316
289
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
clearInterval(interval)
|
|
320
|
-
reject(new Error('Timeout exceeded while waiting for files to be downloaded.'))
|
|
321
|
-
}, maxWaitTime)
|
|
322
|
-
}
|
|
290
|
+
setTimeout(poll, 60000)
|
|
291
|
+
})
|
|
323
292
|
|
|
324
293
|
/**
|
|
325
294
|
* This method is used to coordinate the waiting queues of ceremony circuits.
|
|
@@ -341,7 +310,7 @@ const waitForFileDownload = (
|
|
|
341
310
|
* - Just completed a contribution or all contributions for each circuit. If yes, coordinate (multi-participant scenario).
|
|
342
311
|
*/
|
|
343
312
|
export const coordinateCeremonyParticipant = functionsV1
|
|
344
|
-
.region(
|
|
313
|
+
.region("europe-west1")
|
|
345
314
|
.runWith({
|
|
346
315
|
memory: "512MB"
|
|
347
316
|
})
|
|
@@ -442,7 +411,6 @@ export const coordinateCeremonyParticipant = functionsV1
|
|
|
442
411
|
}
|
|
443
412
|
})
|
|
444
413
|
|
|
445
|
-
|
|
446
414
|
/**
|
|
447
415
|
* Recursive function to check whether an EC2 is in a running state
|
|
448
416
|
* @notice required step to run commands
|
|
@@ -451,23 +419,18 @@ export const coordinateCeremonyParticipant = functionsV1
|
|
|
451
419
|
* @param attempts <number> - how many times to retry before failing
|
|
452
420
|
* @returns <Promise<boolean>> - whether the VM was started
|
|
453
421
|
*/
|
|
454
|
-
const checkIfVMRunning = async (
|
|
455
|
-
ec2: EC2Client,
|
|
456
|
-
vmInstanceId: string,
|
|
457
|
-
attempts = 5
|
|
458
|
-
): Promise<boolean> => {
|
|
422
|
+
const checkIfVMRunning = async (ec2: EC2Client, vmInstanceId: string, attempts = 5): Promise<boolean> => {
|
|
459
423
|
// if we tried 5 times, then throw an error
|
|
460
424
|
if (attempts <= 0) logAndThrowError(SPECIFIC_ERRORS.SE_VM_NOT_RUNNING)
|
|
461
425
|
|
|
462
|
-
await sleep(60000)
|
|
463
|
-
const isVMRunning = await checkIfRunning(ec2, vmInstanceId)
|
|
426
|
+
await sleep(60000) // Wait for 1 min
|
|
427
|
+
const isVMRunning = await checkIfRunning(ec2, vmInstanceId)
|
|
464
428
|
|
|
465
429
|
if (!isVMRunning) {
|
|
466
430
|
printLog(`VM not running, ${attempts - 1} attempts remaining. Retrying in 1 minute...`, LogLevel.DEBUG)
|
|
467
|
-
return
|
|
468
|
-
} else {
|
|
469
|
-
return true
|
|
431
|
+
return checkIfVMRunning(ec2, vmInstanceId, attempts - 1)
|
|
470
432
|
}
|
|
433
|
+
return true
|
|
471
434
|
}
|
|
472
435
|
|
|
473
436
|
/**
|
|
@@ -497,7 +460,7 @@ const checkIfVMRunning = async (
|
|
|
497
460
|
* 2) Send all updates atomically to the Firestore database.
|
|
498
461
|
*/
|
|
499
462
|
export const verifycontribution = functionsV2.https.onCall(
|
|
500
|
-
{ memory: "16GiB", timeoutSeconds: 3600, region:
|
|
463
|
+
{ memory: "16GiB", timeoutSeconds: 3600, region: "europe-west1" },
|
|
501
464
|
async (request: functionsV2.https.CallableRequest<VerifyContributionData>): Promise<any> => {
|
|
502
465
|
if (!request.auth || (!request.auth.token.participant && !request.auth.token.coordinator))
|
|
503
466
|
logAndThrowError(SPECIFIC_ERRORS.SE_AUTH_NO_CURRENT_AUTH_USER)
|
|
@@ -665,9 +628,6 @@ export const verifycontribution = functionsV2.https.onCall(
|
|
|
665
628
|
verificationTranscriptTemporaryLocalPath,
|
|
666
629
|
true
|
|
667
630
|
)
|
|
668
|
-
|
|
669
|
-
// Stop VM instance.
|
|
670
|
-
await stopEC2Instance(ec2, vmInstanceId)
|
|
671
631
|
} else {
|
|
672
632
|
// Upload verification transcript.
|
|
673
633
|
/// nb. do not use multi-part upload here due to small file size.
|
|
@@ -744,6 +704,17 @@ export const verifycontribution = functionsV2.https.onCall(
|
|
|
744
704
|
})
|
|
745
705
|
}
|
|
746
706
|
|
|
707
|
+
// Stop VM instance
|
|
708
|
+
if (isUsingVM) {
|
|
709
|
+
// using try and catch as the VM stopping function can throw
|
|
710
|
+
// however we want to continue without stopping as the
|
|
711
|
+
// verification was valid, and inform the coordinator
|
|
712
|
+
try {
|
|
713
|
+
await stopEC2Instance(ec2, vmInstanceId)
|
|
714
|
+
} catch (error: any) {
|
|
715
|
+
printLog(`Error while stopping VM instance ${vmInstanceId} - Error ${error}`, LogLevel.WARN)
|
|
716
|
+
}
|
|
717
|
+
}
|
|
747
718
|
// Step (1.A.4.C)
|
|
748
719
|
if (!isFinalizing) {
|
|
749
720
|
// Step (1.A.4.C.1)
|
|
@@ -764,6 +735,8 @@ export const verifycontribution = functionsV2.https.onCall(
|
|
|
764
735
|
: verifyCloudFunctionTime
|
|
765
736
|
|
|
766
737
|
// Prepare tx to update circuit average contribution/verification time.
|
|
738
|
+
const updatedCircuitDoc = await getDocumentById(getCircuitsCollectionPath(ceremonyId), circuitId)
|
|
739
|
+
const { waitingQueue: updatedWaitingQueue } = updatedCircuitDoc.data()!
|
|
767
740
|
/// @dev this must happen only for valid contributions.
|
|
768
741
|
batch.update(circuitDoc.ref, {
|
|
769
742
|
avgTimings: {
|
|
@@ -776,7 +749,7 @@ export const verifycontribution = functionsV2.https.onCall(
|
|
|
776
749
|
: avgVerifyCloudFunctionTime
|
|
777
750
|
},
|
|
778
751
|
waitingQueue: {
|
|
779
|
-
...
|
|
752
|
+
...updatedWaitingQueue,
|
|
780
753
|
completedContributions: isContributionValid
|
|
781
754
|
? completedContributions + 1
|
|
782
755
|
: completedContributions,
|
|
@@ -835,9 +808,7 @@ export const verifycontribution = functionsV2.https.onCall(
|
|
|
835
808
|
printLog(`Starting the execution of command ${commandId}`, LogLevel.DEBUG)
|
|
836
809
|
|
|
837
810
|
// Step (1.A.3.3).
|
|
838
|
-
return
|
|
839
|
-
waitForVMCommandExecution(resolve, reject, ssm, vmInstanceId, commandId)
|
|
840
|
-
)
|
|
811
|
+
return waitForVMCommandExecution(ssm, vmInstanceId, commandId)
|
|
841
812
|
.then(async () => {
|
|
842
813
|
// Command execution successfully completed.
|
|
843
814
|
printLog(`Command ${commandId} execution has been successfully completed`, LogLevel.DEBUG)
|
|
@@ -849,76 +820,57 @@ export const verifycontribution = functionsV2.https.onCall(
|
|
|
849
820
|
|
|
850
821
|
logAndThrowError(COMMON_ERRORS.CM_INVALID_COMMAND_EXECUTION)
|
|
851
822
|
})
|
|
852
|
-
}
|
|
853
|
-
// CF approach.
|
|
854
|
-
printLog(`CF mechanism`, LogLevel.DEBUG)
|
|
855
|
-
|
|
856
|
-
const potStoragePath = getPotStorageFilePath(files.potFilename)
|
|
857
|
-
const firstZkeyStoragePath = getZkeyStorageFilePath(prefix, `${prefix}_${genesisZkeyIndex}.zkey`)
|
|
858
|
-
// Prepare temporary file paths.
|
|
859
|
-
// (nb. these are needed to download the necessary artifacts for verification from AWS S3).
|
|
860
|
-
verificationTranscriptTemporaryLocalPath = createTemporaryLocalPath(
|
|
861
|
-
verificationTranscriptCompleteFilename
|
|
862
|
-
)
|
|
863
|
-
const potTempFilePath = createTemporaryLocalPath(`${circuitId}_${participantDoc.id}.pot`)
|
|
864
|
-
const firstZkeyTempFilePath = createTemporaryLocalPath(`${circuitId}_${participantDoc.id}_genesis.zkey`)
|
|
865
|
-
const lastZkeyTempFilePath = createTemporaryLocalPath(`${circuitId}_${participantDoc.id}_last.zkey`)
|
|
866
|
-
|
|
867
|
-
// Create and populate transcript.
|
|
868
|
-
const transcriptLogger = createCustomLoggerForFile(verificationTranscriptTemporaryLocalPath)
|
|
869
|
-
transcriptLogger.info(
|
|
870
|
-
`${
|
|
871
|
-
isFinalizing ? `Final verification` : `Verification`
|
|
872
|
-
} transcript for ${prefix} circuit Phase 2 contribution.\n${
|
|
873
|
-
isFinalizing ? `Coordinator ` : `Contributor # ${Number(lastZkeyIndex)}`
|
|
874
|
-
} (${contributorOrCoordinatorIdentifier})\n`
|
|
875
|
-
)
|
|
876
|
-
|
|
877
|
-
// Step (1.A.2).
|
|
878
|
-
await downloadArtifactFromS3Bucket(bucketName, potStoragePath, potTempFilePath)
|
|
879
|
-
await downloadArtifactFromS3Bucket(bucketName, firstZkeyStoragePath, firstZkeyTempFilePath)
|
|
880
|
-
await downloadArtifactFromS3Bucket(bucketName, lastZkeyStoragePath, lastZkeyTempFilePath)
|
|
823
|
+
}
|
|
881
824
|
|
|
882
|
-
|
|
825
|
+
// CF approach.
|
|
826
|
+
printLog(`CF mechanism`, LogLevel.DEBUG)
|
|
827
|
+
|
|
828
|
+
const potStoragePath = getPotStorageFilePath(files.potFilename)
|
|
829
|
+
const firstZkeyStoragePath = getZkeyStorageFilePath(prefix, `${prefix}_${genesisZkeyIndex}.zkey`)
|
|
830
|
+
// Prepare temporary file paths.
|
|
831
|
+
// (nb. these are needed to download the necessary artifacts for verification from AWS S3).
|
|
832
|
+
verificationTranscriptTemporaryLocalPath = createTemporaryLocalPath(verificationTranscriptCompleteFilename)
|
|
833
|
+
const potTempFilePath = createTemporaryLocalPath(`${circuitId}_${participantDoc.id}.pot`)
|
|
834
|
+
const firstZkeyTempFilePath = createTemporaryLocalPath(`${circuitId}_${participantDoc.id}_genesis.zkey`)
|
|
835
|
+
const lastZkeyTempFilePath = createTemporaryLocalPath(`${circuitId}_${participantDoc.id}_last.zkey`)
|
|
836
|
+
|
|
837
|
+
// Create and populate transcript.
|
|
838
|
+
const transcriptLogger = createCustomLoggerForFile(verificationTranscriptTemporaryLocalPath)
|
|
839
|
+
transcriptLogger.info(
|
|
840
|
+
`${
|
|
841
|
+
isFinalizing ? `Final verification` : `Verification`
|
|
842
|
+
} transcript for ${prefix} circuit Phase 2 contribution.\n${
|
|
843
|
+
isFinalizing ? `Coordinator ` : `Contributor # ${Number(lastZkeyIndex)}`
|
|
844
|
+
} (${contributorOrCoordinatorIdentifier})\n`
|
|
845
|
+
)
|
|
883
846
|
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
.then(async () => {
|
|
889
|
-
printLog(`Downloads from AWS S3 bucket completed - ceremony ${ceremonyId} circuit ${circuitId}`, LogLevel.DEBUG)
|
|
890
|
-
|
|
891
|
-
// Step (1.A.4).
|
|
892
|
-
isContributionValid = await zKey.verifyFromInit(
|
|
893
|
-
firstZkeyTempFilePath,
|
|
894
|
-
potTempFilePath,
|
|
895
|
-
lastZkeyTempFilePath,
|
|
896
|
-
transcriptLogger
|
|
897
|
-
)
|
|
898
|
-
|
|
899
|
-
// Compute contribution hash.
|
|
900
|
-
lastZkeyBlake2bHash = await blake512FromPath(lastZkeyTempFilePath)
|
|
901
|
-
|
|
902
|
-
// Free resources by unlinking temporary folders.
|
|
903
|
-
// Do not free-up verification transcript path here.
|
|
904
|
-
try {
|
|
905
|
-
fs.unlinkSync(potTempFilePath)
|
|
906
|
-
fs.unlinkSync(firstZkeyTempFilePath)
|
|
907
|
-
fs.unlinkSync(lastZkeyTempFilePath)
|
|
908
|
-
} catch (error: any) {
|
|
909
|
-
printLog(`Error while unlinking temporary files - Error ${error}`, LogLevel.WARN)
|
|
910
|
-
}
|
|
847
|
+
// Step (1.A.2).
|
|
848
|
+
await downloadArtifactFromS3Bucket(bucketName, potStoragePath, potTempFilePath)
|
|
849
|
+
await downloadArtifactFromS3Bucket(bucketName, firstZkeyStoragePath, firstZkeyTempFilePath)
|
|
850
|
+
await downloadArtifactFromS3Bucket(bucketName, lastZkeyStoragePath, lastZkeyTempFilePath)
|
|
911
851
|
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
852
|
+
// Step (1.A.4).
|
|
853
|
+
isContributionValid = await zKey.verifyFromInit(
|
|
854
|
+
firstZkeyTempFilePath,
|
|
855
|
+
potTempFilePath,
|
|
856
|
+
lastZkeyTempFilePath,
|
|
857
|
+
transcriptLogger
|
|
858
|
+
)
|
|
918
859
|
|
|
919
|
-
|
|
920
|
-
|
|
860
|
+
// Compute contribution hash.
|
|
861
|
+
lastZkeyBlake2bHash = await blake512FromPath(lastZkeyTempFilePath)
|
|
862
|
+
|
|
863
|
+
// Free resources by unlinking temporary folders.
|
|
864
|
+
// Do not free-up verification transcript path here.
|
|
865
|
+
try {
|
|
866
|
+
fs.unlinkSync(potTempFilePath)
|
|
867
|
+
fs.unlinkSync(firstZkeyTempFilePath)
|
|
868
|
+
fs.unlinkSync(lastZkeyTempFilePath)
|
|
869
|
+
} catch (error: any) {
|
|
870
|
+
printLog(`Error while unlinking temporary files - Error ${error}`, LogLevel.WARN)
|
|
921
871
|
}
|
|
872
|
+
|
|
873
|
+
await completeVerification()
|
|
922
874
|
}
|
|
923
875
|
}
|
|
924
876
|
)
|
|
@@ -929,7 +881,7 @@ export const verifycontribution = functionsV2.https.onCall(
|
|
|
929
881
|
* this does not happen if the participant is actually the coordinator who is finalizing the ceremony.
|
|
930
882
|
*/
|
|
931
883
|
export const refreshParticipantAfterContributionVerification = functionsV1
|
|
932
|
-
.region(
|
|
884
|
+
.region("europe-west1")
|
|
933
885
|
.runWith({
|
|
934
886
|
memory: "512MB"
|
|
935
887
|
})
|
|
@@ -1012,7 +964,7 @@ export const refreshParticipantAfterContributionVerification = functionsV1
|
|
|
1012
964
|
* and verification key extracted from the circuit final contribution (as part of the ceremony finalization process).
|
|
1013
965
|
*/
|
|
1014
966
|
export const finalizeCircuit = functionsV1
|
|
1015
|
-
.region(
|
|
967
|
+
.region("europe-west1")
|
|
1016
968
|
.runWith({
|
|
1017
969
|
memory: "512MB"
|
|
1018
970
|
})
|