@devtion/backend 0.0.0-3df1645 → 0.0.0-477457c

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.
Files changed (50) hide show
  1. package/README.md +2 -2
  2. package/dist/src/functions/index.js +627 -345
  3. package/dist/src/functions/index.mjs +628 -348
  4. package/dist/src/functions/types/functions/bandada.d.ts +4 -0
  5. package/dist/src/functions/types/functions/bandada.d.ts.map +1 -0
  6. package/dist/{types → src/functions/types}/functions/ceremony.d.ts.map +1 -1
  7. package/dist/{types → src/functions/types}/functions/circuit.d.ts.map +1 -1
  8. package/dist/{types → src/functions/types}/functions/index.d.ts +2 -0
  9. package/dist/{types → src/functions/types}/functions/index.d.ts.map +1 -1
  10. package/dist/src/functions/types/functions/siwe.d.ts +4 -0
  11. package/dist/src/functions/types/functions/siwe.d.ts.map +1 -0
  12. package/dist/{types → src/functions/types}/functions/storage.d.ts.map +1 -1
  13. package/dist/{types → src/functions/types}/functions/timeout.d.ts.map +1 -1
  14. package/dist/{types → src/functions/types}/functions/user.d.ts.map +1 -1
  15. package/dist/{types → src/functions/types}/lib/errors.d.ts +2 -1
  16. package/dist/src/functions/types/lib/errors.d.ts.map +1 -0
  17. package/dist/{types → src/functions/types}/lib/services.d.ts +7 -0
  18. package/dist/src/functions/types/lib/services.d.ts.map +1 -0
  19. package/dist/src/functions/types/lib/utils.d.ts.map +1 -0
  20. package/dist/{types → src/functions/types}/types/index.d.ts +56 -0
  21. package/dist/src/functions/types/types/index.d.ts.map +1 -0
  22. package/package.json +8 -7
  23. package/src/functions/bandada.ts +154 -0
  24. package/src/functions/ceremony.ts +11 -7
  25. package/src/functions/circuit.ts +414 -384
  26. package/src/functions/index.ts +2 -0
  27. package/src/functions/participant.ts +8 -8
  28. package/src/functions/siwe.ts +77 -0
  29. package/src/functions/storage.ts +7 -6
  30. package/src/functions/timeout.ts +14 -13
  31. package/src/functions/user.ts +6 -5
  32. package/src/lib/errors.ts +6 -1
  33. package/src/lib/services.ts +36 -0
  34. package/src/lib/utils.ts +8 -6
  35. package/src/types/declarations.d.ts +1 -0
  36. package/src/types/index.ts +60 -0
  37. package/dist/types/lib/errors.d.ts.map +0 -1
  38. package/dist/types/lib/services.d.ts.map +0 -1
  39. package/dist/types/lib/utils.d.ts.map +0 -1
  40. package/dist/types/types/index.d.ts.map +0 -1
  41. /package/dist/{types → src/functions/types}/functions/ceremony.d.ts +0 -0
  42. /package/dist/{types → src/functions/types}/functions/circuit.d.ts +0 -0
  43. /package/dist/{types → src/functions/types}/functions/participant.d.ts +0 -0
  44. /package/dist/{types → src/functions/types}/functions/participant.d.ts.map +0 -0
  45. /package/dist/{types → src/functions/types}/functions/storage.d.ts +0 -0
  46. /package/dist/{types → src/functions/types}/functions/timeout.d.ts +0 -0
  47. /package/dist/{types → src/functions/types}/functions/user.d.ts +0 -0
  48. /package/dist/{types → src/functions/types}/lib/utils.d.ts +0 -0
  49. /package/dist/{types → src/functions/types}/types/enums.d.ts +0 -0
  50. /package/dist/{types → src/functions/types}/types/enums.d.ts.map +0 -0
@@ -40,6 +40,8 @@ import {
40
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
47
  import { COMMON_ERRORS, logAndThrowError, makeError, printLog, SPECIFIC_ERRORS } from "../lib/errors"
@@ -57,8 +59,6 @@ import {
57
59
  sleep,
58
60
  uploadFileToBucket
59
61
  } from "../lib/utils"
60
- import { EC2Client } from "@aws-sdk/client-ec2"
61
- import { HttpsError } from "firebase-functions/v2/https"
62
62
 
63
63
  dotenv.config()
64
64
 
@@ -115,7 +115,7 @@ const coordinate = async (
115
115
  if (isSingleParticipantCoordination) {
116
116
  // Scenario (A).
117
117
  if (emptyWaitingQueue) {
118
- printLog(`Coordinate - executing scenario A - emptyWaitingQueue`, LogLevel.DEBUG)
118
+ printLog(`Coordinate - executing scenario A - emptyWaitingQueue`, LogLevel.INFO)
119
119
 
120
120
  // Update.
121
121
  newCurrentContributorId = participant.id
@@ -127,7 +127,7 @@ const coordinate = async (
127
127
  else if (participantResumingAfterTimeoutExpiration) {
128
128
  printLog(
129
129
  `Coordinate - executing scenario A - single - participantResumingAfterTimeoutExpiration`,
130
- LogLevel.DEBUG
130
+ LogLevel.INFO
131
131
  )
132
132
 
133
133
  newParticipantStatus = ParticipantStatus.CONTRIBUTING
@@ -136,7 +136,7 @@ const coordinate = async (
136
136
  }
137
137
  // Scenario (B).
138
138
  else if (participantIsNotCurrentContributor) {
139
- printLog(`Coordinate - executing scenario B - single - participantIsNotCurrentContributor`, LogLevel.DEBUG)
139
+ printLog(`Coordinate - executing scenario B - single - participantIsNotCurrentContributor`, LogLevel.INFO)
140
140
 
141
141
  newCurrentContributorId = currentContributor
142
142
  newParticipantStatus = ParticipantStatus.WAITING
@@ -160,7 +160,7 @@ const coordinate = async (
160
160
  } else if (participantIsCurrentContributor && participantCompletedOneOrAllContributions && !!ceremonyId) {
161
161
  printLog(
162
162
  `Coordinate - executing scenario C - multi - participantIsCurrentContributor && participantCompletedOneOrAllContributions`,
163
- LogLevel.DEBUG
163
+ LogLevel.INFO
164
164
  )
165
165
 
166
166
  newParticipantStatus = ParticipantStatus.CONTRIBUTING
@@ -190,7 +190,7 @@ const coordinate = async (
190
190
 
191
191
  printLog(
192
192
  `Participant ${newCurrentContributorId} is the new current contributor for circuit ${circuit.id}`,
193
- LogLevel.DEBUG
193
+ LogLevel.INFO
194
194
  )
195
195
  }
196
196
  }
@@ -276,8 +276,8 @@ const waitForVMCommandExecution = (ssm: SSMClient, vmInstanceId: string, command
276
276
  // if it errors out, let's just log it as a warning so the coordinator is aware
277
277
  try {
278
278
  await stopEC2Instance(ec2, vmInstanceId)
279
- } catch (error: any) {
280
- printLog(`Error while stopping VM instance ${vmInstanceId} - Error ${error}`, LogLevel.WARN)
279
+ } catch (stopError: any) {
280
+ printLog(`Error while stopping VM instance ${vmInstanceId} - Error ${stopError}`, LogLevel.WARN)
281
281
  }
282
282
 
283
283
  if (!error.toString().includes(commandId)) logAndThrowError(COMMON_ERRORS.CM_INVALID_COMMAND_EXECUTION)
@@ -312,7 +312,7 @@ const waitForVMCommandExecution = (ssm: SSMClient, vmInstanceId: string, command
312
312
  export const coordinateCeremonyParticipant = functionsV1
313
313
  .region("europe-west1")
314
314
  .runWith({
315
- memory: "512MB"
315
+ memory: "1GB"
316
316
  })
317
317
  .firestore.document(
318
318
  `${commonTerms.collections.ceremonies.name}/{ceremonyId}/${commonTerms.collections.participants.name}/{participantId}`
@@ -346,10 +346,10 @@ export const coordinateCeremonyParticipant = functionsV1
346
346
  contributionStep: changedContributionStep
347
347
  } = changedParticipant.data()!
348
348
 
349
- printLog(`Coordinate participant ${exParticipant.id} for ceremony ${ceremonyId}`, LogLevel.DEBUG)
349
+ printLog(`Coordinate participant ${exParticipant.id} for ceremony ${ceremonyId}`, LogLevel.INFO)
350
350
  printLog(
351
351
  `Participant status: ${prevStatus} => ${changedStatus} - Participant contribution step: ${prevContributionStep} => ${changedContributionStep}`,
352
- LogLevel.DEBUG
352
+ LogLevel.INFO
353
353
  )
354
354
 
355
355
  // Define pre-conditions.
@@ -370,8 +370,8 @@ export const coordinateCeremonyParticipant = functionsV1
370
370
 
371
371
  const participantCompletedContribution =
372
372
  prevContributionProgress === changedContributionProgress &&
373
- prevStatus === ParticipantStatus.CONTRIBUTING &&
374
- prevContributionStep === ParticipantContributionStep.VERIFYING &&
373
+ (prevStatus === ParticipantStatus.CONTRIBUTING ||
374
+ prevContributionStep === ParticipantContributionStep.VERIFYING) &&
375
375
  changedStatus === ParticipantStatus.CONTRIBUTED &&
376
376
  changedContributionStep === ParticipantContributionStep.COMPLETED
377
377
 
@@ -384,7 +384,7 @@ export const coordinateCeremonyParticipant = functionsV1
384
384
  // Step (2.A).
385
385
  printLog(
386
386
  `Participant is ready for first contribution (${participantReadyForFirstContribution}) or for the next contribution (${participantReadyForNextContribution}) or is resuming after a timeout expiration (${participantResumingContributionAfterTimeout})`,
387
- LogLevel.DEBUG
387
+ LogLevel.INFO
388
388
  )
389
389
 
390
390
  // Get the circuit.
@@ -398,7 +398,7 @@ export const coordinateCeremonyParticipant = functionsV1
398
398
  // Step (2.B).
399
399
  printLog(
400
400
  `Participant completed a contribution (${participantCompletedContribution}) or every contribution for each circuit (${participantCompletedEveryCircuitContribution})`,
401
- LogLevel.DEBUG
401
+ LogLevel.INFO
402
402
  )
403
403
 
404
404
  // Get the circuit.
@@ -428,10 +428,9 @@ const checkIfVMRunning = async (ec2: EC2Client, vmInstanceId: string, attempts =
428
428
 
429
429
  if (!isVMRunning) {
430
430
  printLog(`VM not running, ${attempts - 1} attempts remaining. Retrying in 1 minute...`, LogLevel.DEBUG)
431
- return await checkIfVMRunning(ec2, vmInstanceId, attempts - 1)
432
- } else {
433
- return true
431
+ return checkIfVMRunning(ec2, vmInstanceId, attempts - 1)
434
432
  }
433
+ return true
435
434
  }
436
435
 
437
436
  /**
@@ -461,417 +460,448 @@ const checkIfVMRunning = async (ec2: EC2Client, vmInstanceId: string, attempts =
461
460
  * 2) Send all updates atomically to the Firestore database.
462
461
  */
463
462
  export const verifycontribution = functionsV2.https.onCall(
464
- { memory: "16GiB", timeoutSeconds: 3600, region: "europe-west1" },
463
+ { memory: "32GiB", timeoutSeconds: 3600, region: "europe-west1", cpu: 8 },
465
464
  async (request: functionsV2.https.CallableRequest<VerifyContributionData>): Promise<any> => {
466
- if (!request.auth || (!request.auth.token.participant && !request.auth.token.coordinator))
467
- logAndThrowError(SPECIFIC_ERRORS.SE_AUTH_NO_CURRENT_AUTH_USER)
468
-
469
- if (
470
- !request.data.ceremonyId ||
471
- !request.data.circuitId ||
472
- !request.data.contributorOrCoordinatorIdentifier ||
473
- !request.data.bucketName
474
- )
475
- logAndThrowError(COMMON_ERRORS.CM_MISSING_OR_WRONG_INPUT_DATA)
476
-
477
- if (
478
- !process.env.CUSTOM_CONTRIBUTION_VERIFICATION_SOFTWARE_NAME ||
479
- !process.env.CUSTOM_CONTRIBUTION_VERIFICATION_SOFTWARE_VERSION ||
480
- !process.env.CUSTOM_CONTRIBUTION_VERIFICATION_SOFTWARE_COMMIT_HASH
481
- )
482
- logAndThrowError(COMMON_ERRORS.CM_WRONG_CONFIGURATION)
483
-
484
- // Step (0).
465
+ try {
466
+ if (!request.auth || (!request.auth.token.participant && !request.auth.token.coordinator))
467
+ logAndThrowError(SPECIFIC_ERRORS.SE_AUTH_NO_CURRENT_AUTH_USER)
468
+
469
+ if (
470
+ !request.data.ceremonyId ||
471
+ !request.data.circuitId ||
472
+ !request.data.contributorOrCoordinatorIdentifier ||
473
+ !request.data.bucketName
474
+ )
475
+ logAndThrowError(COMMON_ERRORS.CM_MISSING_OR_WRONG_INPUT_DATA)
485
476
 
486
- // Prepare and start timer.
487
- const verifyContributionTimer = new Timer({ label: commonTerms.cloudFunctionsNames.verifyContribution })
488
- verifyContributionTimer.start()
477
+ if (
478
+ !process.env.CUSTOM_CONTRIBUTION_VERIFICATION_SOFTWARE_NAME ||
479
+ !process.env.CUSTOM_CONTRIBUTION_VERIFICATION_SOFTWARE_VERSION ||
480
+ !process.env.CUSTOM_CONTRIBUTION_VERIFICATION_SOFTWARE_COMMIT_HASH
481
+ )
482
+ logAndThrowError(COMMON_ERRORS.CM_WRONG_CONFIGURATION)
483
+
484
+ const BUCKET_NAME_REGEX = /^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$/
485
+ if (!BUCKET_NAME_REGEX.test(request.data.bucketName)) logAndThrowError(SPECIFIC_ERRORS.WRONG_BUCKET_NAME)
486
+
487
+ // Step (0).
488
+
489
+ // Prepare and start timer.
490
+ const verifyContributionTimer = new Timer({ label: commonTerms.cloudFunctionsNames.verifyContribution })
491
+ verifyContributionTimer.start()
492
+
493
+ // Get DB.
494
+ const firestore = admin.firestore()
495
+ // Prepare batch of txs.
496
+ const batch = firestore.batch()
497
+
498
+ // Extract data.
499
+ const { ceremonyId, circuitId, contributorOrCoordinatorIdentifier, bucketName } = request.data
500
+ const userId = request.auth?.uid
501
+
502
+ // Look for the ceremony, circuit and participant document.
503
+ const ceremonyDoc = await getDocumentById(commonTerms.collections.ceremonies.name, ceremonyId)
504
+ const circuitDoc = await getDocumentById(getCircuitsCollectionPath(ceremonyId), circuitId)
505
+ const participantDoc = await getDocumentById(getParticipantsCollectionPath(ceremonyId), userId!)
506
+
507
+ if (!ceremonyDoc.data() || !circuitDoc.data() || !participantDoc.data())
508
+ logAndThrowError(COMMON_ERRORS.CM_INEXISTENT_DOCUMENT_DATA)
509
+
510
+ // Extract documents data.
511
+ const { state } = ceremonyDoc.data()!
512
+ const { status, contributions, verificationStartedAt, contributionStartedAt } = participantDoc.data()!
513
+ const { waitingQueue, prefix, avgTimings, verification, files } = circuitDoc.data()!
514
+ const { completedContributions, failedContributions } = waitingQueue
515
+ const {
516
+ contributionComputation: avgContributionComputationTime,
517
+ fullContribution: avgFullContributionTime,
518
+ verifyCloudFunction: avgVerifyCloudFunctionTime
519
+ } = avgTimings
520
+ const { cfOrVm, vm } = verification
521
+ // we might not have it if the circuit is not using VM.
522
+ let vmInstanceId: string = ""
523
+ if (vm) vmInstanceId = vm.vmInstanceId
489
524
 
490
- // Get DB.
491
- const firestore = admin.firestore()
492
- // Prepare batch of txs.
493
- const batch = firestore.batch()
525
+ // Define pre-conditions.
526
+ const isFinalizing = state === CeremonyState.CLOSED && request.auth && request.auth.token.coordinator // true only when the coordinator verifies the final contributions.
527
+ const isContributing = status === ParticipantStatus.CONTRIBUTING
528
+ const isUsingVM = cfOrVm === CircuitContributionVerificationMechanism.VM && !!vmInstanceId
529
+
530
+ // Prepare state.
531
+ let isContributionValid = false
532
+ let verifyCloudFunctionExecutionTime = 0 // time spent while executing the verify contribution cloud function.
533
+ let verifyCloudFunctionTime = 0 // time spent while executing the core business logic of this cloud function.
534
+ let fullContributionTime = 0 // time spent while doing non-verification contributions tasks (download, compute, upload).
535
+ let contributionComputationTime = 0 // time spent while computing the contribution.
536
+ let lastZkeyBlake2bHash: string = "" // the Blake2B hash of the last zKey.
537
+ let verificationTranscriptTemporaryLocalPath: string = "" // the local temporary path for the verification transcript.
538
+ let transcriptBlake2bHash: string = "" // the Blake2B hash of the verification transcript.
539
+ let commandId: string = "" // the unique identifier of the VM command.
540
+
541
+ // Derive necessary data.
542
+ const lastZkeyIndex = formatZkeyIndex(completedContributions + 1)
543
+ const verificationTranscriptCompleteFilename = `${prefix}_${
544
+ isFinalizing
545
+ ? `${contributorOrCoordinatorIdentifier}_${finalContributionIndex}_verification_transcript.log`
546
+ : `${lastZkeyIndex}_${contributorOrCoordinatorIdentifier}_verification_transcript.log`
547
+ }`
548
+
549
+ const lastZkeyFilename = `${prefix}_${isFinalizing ? finalContributionIndex : lastZkeyIndex}.zkey`
550
+
551
+ // Prepare state for VM verification (if needed).
552
+ const ec2 = await createEC2Client()
553
+ const ssm = await createSSMClient()
554
+
555
+ // Step (1.A.1).
556
+ // Get storage paths.
557
+ const verificationTranscriptStoragePathAndFilename = getTranscriptStorageFilePath(
558
+ prefix,
559
+ verificationTranscriptCompleteFilename
560
+ )
561
+ // the zKey storage path is required to be sent to the VM api
562
+ const lastZkeyStoragePath = getZkeyStorageFilePath(
563
+ prefix,
564
+ `${prefix}_${isFinalizing ? finalContributionIndex : lastZkeyIndex}.zkey`
565
+ )
494
566
 
495
- // Extract data.
496
- const { ceremonyId, circuitId, contributorOrCoordinatorIdentifier, bucketName } = request.data
497
- const userId = request.auth?.uid
567
+ const verificationTaskTimer = new Timer({ label: `${ceremonyId}-${circuitId}-${participantDoc.id}` })
498
568
 
499
- // Look for the ceremony, circuit and participant document.
500
- const ceremonyDoc = await getDocumentById(commonTerms.collections.ceremonies.name, ceremonyId)
501
- const circuitDoc = await getDocumentById(getCircuitsCollectionPath(ceremonyId), circuitId)
502
- const participantDoc = await getDocumentById(getParticipantsCollectionPath(ceremonyId), userId!)
569
+ const dumpLog = async (path: string): Promise<void> => {
570
+ printLog(`transcript >>>>>>`, LogLevel.DEBUG)
571
+ try {
572
+ const data = await fs.promises.readFile(path, "utf8")
573
+ printLog(data, LogLevel.DEBUG)
574
+ } catch (readError: any) {
575
+ printLog(readError, LogLevel.ERROR)
576
+ }
577
+ }
503
578
 
504
- if (!ceremonyDoc.data() || !circuitDoc.data() || !participantDoc.data())
505
- logAndThrowError(COMMON_ERRORS.CM_INEXISTENT_DOCUMENT_DATA)
579
+ const completeVerification = async () => {
580
+ // Stop verification task timer.
581
+ printLog("Completing verification", LogLevel.DEBUG)
582
+ verificationTaskTimer.stop()
583
+ verifyCloudFunctionExecutionTime = verificationTaskTimer.ms()
506
584
 
507
- // Extract documents data.
508
- const { state } = ceremonyDoc.data()!
509
- const { status, contributions, verificationStartedAt, contributionStartedAt } = participantDoc.data()!
510
- const { waitingQueue, prefix, avgTimings, verification, files } = circuitDoc.data()!
511
- const { completedContributions, failedContributions } = waitingQueue
512
- const {
513
- contributionComputation: avgContributionComputationTime,
514
- fullContribution: avgFullContributionTime,
515
- verifyCloudFunction: avgVerifyCloudFunctionTime
516
- } = avgTimings
517
- const { cfOrVm, vm } = verification
518
- // we might not have it if the circuit is not using VM.
519
- let vmInstanceId: string = ""
520
- if (vm) vmInstanceId = vm.vmInstanceId
585
+ if (isUsingVM) {
586
+ // Create temporary path.
587
+ verificationTranscriptTemporaryLocalPath = createTemporaryLocalPath(
588
+ `${circuitId}_${participantDoc.id}.log`
589
+ )
521
590
 
522
- // Define pre-conditions.
523
- const isFinalizing = state === CeremonyState.CLOSED && request.auth && request.auth.token.coordinator // true only when the coordinator verifies the final contributions.
524
- const isContributing = status === ParticipantStatus.CONTRIBUTING
525
- const isUsingVM = cfOrVm === CircuitContributionVerificationMechanism.VM && !!vmInstanceId
526
-
527
- // Prepare state.
528
- let isContributionValid = false
529
- let verifyCloudFunctionExecutionTime = 0 // time spent while executing the verify contribution cloud function.
530
- let verifyCloudFunctionTime = 0 // time spent while executing the core business logic of this cloud function.
531
- let fullContributionTime = 0 // time spent while doing non-verification contributions tasks (download, compute, upload).
532
- let contributionComputationTime = 0 // time spent while computing the contribution.
533
- let lastZkeyBlake2bHash: string = "" // the Blake2B hash of the last zKey.
534
- let verificationTranscriptTemporaryLocalPath: string = "" // the local temporary path for the verification transcript.
535
- let transcriptBlake2bHash: string = "" // the Blake2B hash of the verification transcript.
536
- let commandId: string = "" // the unique identifier of the VM command.
537
-
538
- // Derive necessary data.
539
- const lastZkeyIndex = formatZkeyIndex(completedContributions + 1)
540
- const verificationTranscriptCompleteFilename = `${prefix}_${
541
- isFinalizing
542
- ? `${contributorOrCoordinatorIdentifier}_${finalContributionIndex}_verification_transcript.log`
543
- : `${lastZkeyIndex}_${contributorOrCoordinatorIdentifier}_verification_transcript.log`
544
- }`
545
-
546
- const lastZkeyFilename = `${prefix}_${isFinalizing ? finalContributionIndex : lastZkeyIndex}.zkey`
547
-
548
- // Prepare state for VM verification (if needed).
549
- const ec2 = await createEC2Client()
550
- const ssm = await createSSMClient()
551
-
552
- // Step (1.A.1).
553
- // Get storage paths.
554
- const verificationTranscriptStoragePathAndFilename = getTranscriptStorageFilePath(
555
- prefix,
556
- verificationTranscriptCompleteFilename
557
- )
558
- // the zKey storage path is required to be sent to the VM api
559
- const lastZkeyStoragePath = getZkeyStorageFilePath(
560
- prefix,
561
- `${prefix}_${isFinalizing ? finalContributionIndex : lastZkeyIndex}.zkey`
562
- )
591
+ await sleep(1000) // wait 1s for file creation.
563
592
 
564
- const verificationTaskTimer = new Timer({ label: `${ceremonyId}-${circuitId}-${participantDoc.id}` })
593
+ // Download from bucket.
594
+ // nb. the transcript MUST be uploaded from the VM by verification commands.
595
+ await downloadArtifactFromS3Bucket(
596
+ bucketName,
597
+ verificationTranscriptStoragePathAndFilename,
598
+ verificationTranscriptTemporaryLocalPath
599
+ )
565
600
 
566
- const completeVerification = async () => {
567
- // Stop verification task timer.
568
- printLog("Completing verification", LogLevel.DEBUG)
569
- verificationTaskTimer.stop()
570
- verifyCloudFunctionExecutionTime = verificationTaskTimer.ms()
601
+ // Read the verification trascript and validate data by checking for core info ("ZKey Ok!").
602
+ const content = fs.readFileSync(verificationTranscriptTemporaryLocalPath, "utf-8")
571
603
 
572
- if (isUsingVM) {
573
- // Create temporary path.
574
- verificationTranscriptTemporaryLocalPath = createTemporaryLocalPath(
575
- `${circuitId}_${participantDoc.id}.log`
576
- )
604
+ if (content.includes("ZKey Ok!")) isContributionValid = true
577
605
 
578
- await sleep(1000) // wait 1s for file creation.
606
+ // If the contribution is valid, then format and store the trascript.
607
+ if (isContributionValid) {
608
+ // eslint-disable-next-line no-control-regex
609
+ const updated = content.replace(/\x1b[[0-9;]*m/g, "")
579
610
 
580
- // Download from bucket.
581
- // nb. the transcript MUST be uploaded from the VM by verification commands.
582
- await downloadArtifactFromS3Bucket(
583
- bucketName,
584
- verificationTranscriptStoragePathAndFilename,
585
- verificationTranscriptTemporaryLocalPath
586
- )
611
+ fs.writeFileSync(verificationTranscriptTemporaryLocalPath, updated)
612
+ }
613
+ }
587
614
 
588
- // Read the verification trascript and validate data by checking for core info ("ZKey Ok!").
589
- const content = fs.readFileSync(verificationTranscriptTemporaryLocalPath, "utf-8")
615
+ printLog(`The contribution has been verified - Result ${isContributionValid}`, LogLevel.DEBUG)
590
616
 
591
- if (content.includes("ZKey Ok!")) isContributionValid = true
617
+ // Create a new contribution document.
618
+ const contributionDoc = await firestore
619
+ .collection(getContributionsCollectionPath(ceremonyId, circuitId))
620
+ .doc()
621
+ .get()
592
622
 
593
- // If the contribution is valid, then format and store the trascript.
623
+ // Step (1.A.4).
594
624
  if (isContributionValid) {
595
- // eslint-disable-next-line no-control-regex
596
- const updated = content.replace(/\x1b[[0-9;]*m/g, "")
597
-
598
- fs.writeFileSync(verificationTranscriptTemporaryLocalPath, updated)
599
- }
600
- }
601
-
602
- printLog(`The contribution has been verified - Result ${isContributionValid}`, LogLevel.DEBUG)
603
-
604
- // Create a new contribution document.
605
- const contributionDoc = await firestore
606
- .collection(getContributionsCollectionPath(ceremonyId, circuitId))
607
- .doc()
608
- .get()
625
+ // Sleep ~3 seconds to wait for verification transcription.
626
+ await sleep(3000)
627
+
628
+ // Step (1.A.4.A.1).
629
+ if (isUsingVM) {
630
+ // Retrieve the contribution hash from the command output.
631
+ lastZkeyBlake2bHash = await retrieveCommandOutput(ssm, vmInstanceId, commandId)
632
+
633
+ const hashRegex = /[a-fA-F0-9]{64}/
634
+ const match = lastZkeyBlake2bHash.match(hashRegex)!
635
+
636
+ lastZkeyBlake2bHash = match.at(0)!
637
+
638
+ // re upload the formatted verification transcript
639
+ await uploadFileToBucket(
640
+ bucketName,
641
+ verificationTranscriptStoragePathAndFilename,
642
+ verificationTranscriptTemporaryLocalPath,
643
+ true
644
+ )
645
+ } else {
646
+ // Upload verification transcript.
647
+ /// nb. do not use multi-part upload here due to small file size.
648
+ await uploadFileToBucket(
649
+ bucketName,
650
+ verificationTranscriptStoragePathAndFilename,
651
+ verificationTranscriptTemporaryLocalPath,
652
+ true
653
+ )
654
+ }
609
655
 
610
- // Step (1.A.4).
611
- if (isContributionValid) {
612
- // Sleep ~3 seconds to wait for verification transcription.
613
- await sleep(3000)
656
+ // Compute verification transcript hash.
657
+ transcriptBlake2bHash = await blake512FromPath(verificationTranscriptTemporaryLocalPath)
614
658
 
615
- // Step (1.A.4.A.1).
616
- if (isUsingVM) {
617
- // Retrieve the contribution hash from the command output.
618
- lastZkeyBlake2bHash = await retrieveCommandOutput(ssm, vmInstanceId, commandId)
659
+ // Free resources by unlinking transcript temporary file.
660
+ fs.unlinkSync(verificationTranscriptTemporaryLocalPath)
619
661
 
620
- const hashRegex = /[a-fA-F0-9]{64}/
621
- const match = lastZkeyBlake2bHash.match(hashRegex)!
662
+ // Filter participant contributions to find the data related to the one verified.
663
+ const participantContributions = contributions.filter(
664
+ (contribution: Contribution) =>
665
+ !!contribution.hash && !!contribution.computationTime && !contribution.doc
666
+ )
622
667
 
623
- lastZkeyBlake2bHash = match.at(0)!
668
+ /// @dev (there must be only one contribution with an empty 'doc' field).
669
+ if (participantContributions.length !== 1)
670
+ logAndThrowError(SPECIFIC_ERRORS.SE_VERIFICATION_NO_PARTICIPANT_CONTRIBUTION_DATA)
671
+
672
+ // Get contribution computation time.
673
+ contributionComputationTime = contributions.at(0).computationTime
674
+
675
+ // Step (1.A.4.A.2).
676
+ batch.create(contributionDoc.ref, {
677
+ participantId: participantDoc.id,
678
+ contributionComputationTime,
679
+ verificationComputationTime: verifyCloudFunctionExecutionTime,
680
+ zkeyIndex: isFinalizing ? finalContributionIndex : lastZkeyIndex,
681
+ files: {
682
+ transcriptFilename: verificationTranscriptCompleteFilename,
683
+ lastZkeyFilename,
684
+ transcriptStoragePath: verificationTranscriptStoragePathAndFilename,
685
+ lastZkeyStoragePath,
686
+ transcriptBlake2bHash,
687
+ lastZkeyBlake2bHash
688
+ },
689
+ verificationSoftware: {
690
+ name: String(process.env.CUSTOM_CONTRIBUTION_VERIFICATION_SOFTWARE_NAME),
691
+ version: String(process.env.CUSTOM_CONTRIBUTION_VERIFICATION_SOFTWARE_VERSION),
692
+ commitHash: String(process.env.CUSTOM_CONTRIBUTION_VERIFICATION_SOFTWARE_COMMIT_HASH)
693
+ },
694
+ valid: isContributionValid,
695
+ lastUpdated: getCurrentServerTimestampInMillis()
696
+ })
624
697
 
625
- // re upload the formatted verification transcript
626
- await uploadFileToBucket(
627
- bucketName,
628
- verificationTranscriptStoragePathAndFilename,
629
- verificationTranscriptTemporaryLocalPath,
630
- true
631
- )
698
+ verifyContributionTimer.stop()
699
+ verifyCloudFunctionTime = verifyContributionTimer.ms()
632
700
  } else {
633
- // Upload verification transcript.
634
- /// nb. do not use multi-part upload here due to small file size.
635
- await uploadFileToBucket(
636
- bucketName,
637
- verificationTranscriptStoragePathAndFilename,
638
- verificationTranscriptTemporaryLocalPath,
639
- true
640
- )
701
+ // Step (1.A.4.B).
702
+
703
+ // Free-up storage by deleting invalid contribution.
704
+ await deleteObject(bucketName, lastZkeyStoragePath)
705
+
706
+ // Step (1.A.4.B.1).
707
+ batch.create(contributionDoc.ref, {
708
+ participantId: participantDoc.id,
709
+ verificationComputationTime: verifyCloudFunctionExecutionTime,
710
+ zkeyIndex: isFinalizing ? finalContributionIndex : lastZkeyIndex,
711
+ verificationSoftware: {
712
+ name: String(process.env.CUSTOM_CONTRIBUTION_VERIFICATION_SOFTWARE_NAME),
713
+ version: String(process.env.CUSTOM_CONTRIBUTION_VERIFICATION_SOFTWARE_VERSION),
714
+ commitHash: String(process.env.CUSTOM_CONTRIBUTION_VERIFICATION_SOFTWARE_COMMIT_HASH)
715
+ },
716
+ valid: isContributionValid,
717
+ lastUpdated: getCurrentServerTimestampInMillis()
718
+ })
641
719
  }
642
720
 
643
- // Compute verification transcript hash.
644
- transcriptBlake2bHash = await blake512FromPath(verificationTranscriptTemporaryLocalPath)
721
+ // Stop VM instance
722
+ if (isUsingVM) {
723
+ // using try and catch as the VM stopping function can throw
724
+ // however we want to continue without stopping as the
725
+ // verification was valid, and inform the coordinator
726
+ try {
727
+ await stopEC2Instance(ec2, vmInstanceId)
728
+ } catch (error: any) {
729
+ printLog(`Error while stopping VM instance ${vmInstanceId} - Error ${error}`, LogLevel.WARN)
730
+ }
731
+ }
732
+ // Step (1.A.4.C)
733
+ if (!isFinalizing) {
734
+ // Step (1.A.4.C.1)
735
+ // Compute new average contribution/verification time.
736
+ fullContributionTime = Number(verificationStartedAt) - Number(contributionStartedAt)
737
+
738
+ const newAvgContributionComputationTime =
739
+ avgContributionComputationTime > 0
740
+ ? (avgContributionComputationTime + contributionComputationTime) / 2
741
+ : contributionComputationTime
742
+ const newAvgFullContributionTime =
743
+ avgFullContributionTime > 0
744
+ ? (avgFullContributionTime + fullContributionTime) / 2
745
+ : fullContributionTime
746
+ const newAvgVerifyCloudFunctionTime =
747
+ avgVerifyCloudFunctionTime > 0
748
+ ? (avgVerifyCloudFunctionTime + verifyCloudFunctionTime) / 2
749
+ : verifyCloudFunctionTime
750
+
751
+ // Prepare tx to update circuit average contribution/verification time.
752
+ const updatedCircuitDoc = await getDocumentById(getCircuitsCollectionPath(ceremonyId), circuitId)
753
+ const { waitingQueue: updatedWaitingQueue } = updatedCircuitDoc.data()!
754
+ /// @dev this must happen only for valid contributions.
755
+ batch.update(circuitDoc.ref, {
756
+ avgTimings: {
757
+ contributionComputation: isContributionValid
758
+ ? newAvgContributionComputationTime
759
+ : avgContributionComputationTime,
760
+ fullContribution: isContributionValid
761
+ ? newAvgFullContributionTime
762
+ : avgFullContributionTime,
763
+ verifyCloudFunction: isContributionValid
764
+ ? newAvgVerifyCloudFunctionTime
765
+ : avgVerifyCloudFunctionTime
766
+ },
767
+ waitingQueue: {
768
+ ...updatedWaitingQueue,
769
+ completedContributions: isContributionValid
770
+ ? completedContributions + 1
771
+ : completedContributions,
772
+ failedContributions: isContributionValid ? failedContributions : failedContributions + 1
773
+ },
774
+ lastUpdated: getCurrentServerTimestampInMillis()
775
+ })
776
+ }
645
777
 
646
- // Free resources by unlinking transcript temporary file.
647
- fs.unlinkSync(verificationTranscriptTemporaryLocalPath)
778
+ // Step (2).
779
+ await batch.commit()
648
780
 
649
- // Filter participant contributions to find the data related to the one verified.
650
- const participantContributions = contributions.filter(
651
- (contribution: Contribution) =>
652
- !!contribution.hash && !!contribution.computationTime && !contribution.doc
781
+ printLog(
782
+ `The contribution #${
783
+ isFinalizing ? finalContributionIndex : lastZkeyIndex
784
+ } of circuit ${circuitId} (ceremony ${ceremonyId}) has been verified as ${
785
+ isContributionValid ? "valid" : "invalid"
786
+ } for the participant ${participantDoc.id}`,
787
+ LogLevel.INFO
653
788
  )
654
-
655
- /// @dev (there must be only one contribution with an empty 'doc' field).
656
- if (participantContributions.length !== 1)
657
- logAndThrowError(SPECIFIC_ERRORS.SE_VERIFICATION_NO_PARTICIPANT_CONTRIBUTION_DATA)
658
-
659
- // Get contribution computation time.
660
- contributionComputationTime = contributions.at(0).computationTime
661
-
662
- // Step (1.A.4.A.2).
663
- batch.create(contributionDoc.ref, {
664
- participantId: participantDoc.id,
665
- contributionComputationTime,
666
- verificationComputationTime: verifyCloudFunctionExecutionTime,
667
- zkeyIndex: isFinalizing ? finalContributionIndex : lastZkeyIndex,
668
- files: {
669
- transcriptFilename: verificationTranscriptCompleteFilename,
670
- lastZkeyFilename,
671
- transcriptStoragePath: verificationTranscriptStoragePathAndFilename,
672
- lastZkeyStoragePath,
673
- transcriptBlake2bHash,
674
- lastZkeyBlake2bHash
675
- },
676
- verificationSoftware: {
677
- name: String(process.env.CUSTOM_CONTRIBUTION_VERIFICATION_SOFTWARE_NAME),
678
- version: String(process.env.CUSTOM_CONTRIBUTION_VERIFICATION_SOFTWARE_VERSION),
679
- commitHash: String(process.env.CUSTOM_CONTRIBUTION_VERIFICATION_SOFTWARE_COMMIT_HASH)
680
- },
681
- valid: isContributionValid,
682
- lastUpdated: getCurrentServerTimestampInMillis()
683
- })
684
-
685
- verifyContributionTimer.stop()
686
- verifyCloudFunctionTime = verifyContributionTimer.ms()
687
- } else {
688
- // Step (1.A.4.B).
689
-
690
- // Free-up storage by deleting invalid contribution.
691
- await deleteObject(bucketName, lastZkeyStoragePath)
692
-
693
- // Step (1.A.4.B.1).
694
- batch.create(contributionDoc.ref, {
695
- participantId: participantDoc.id,
696
- verificationComputationTime: verifyCloudFunctionExecutionTime,
697
- zkeyIndex: isFinalizing ? finalContributionIndex : lastZkeyIndex,
698
- verificationSoftware: {
699
- name: String(process.env.CUSTOM_CONTRIBUTION_VERIFICATION_SOFTWARE_NAME),
700
- version: String(process.env.CUSTOM_CONTRIBUTION_VERIFICATION_SOFTWARE_VERSION),
701
- commitHash: String(process.env.CUSTOM_CONTRIBUTION_VERIFICATION_SOFTWARE_COMMIT_HASH)
702
- },
703
- valid: isContributionValid,
704
- lastUpdated: getCurrentServerTimestampInMillis()
705
- })
706
789
  }
707
790
 
708
- // Stop VM instance
709
- if (isUsingVM) {
710
- // using try and catch as the VM stopping function can throw
711
- // however we want to continue without stopping as the
712
- // verification was valid, and inform the coordinator
713
- try {
714
- await stopEC2Instance(ec2, vmInstanceId)
715
- } catch (error: any) {
716
- printLog(`Error while stopping VM instance ${vmInstanceId} - Error ${error}`, LogLevel.WARN)
717
- }
718
- }
719
- // Step (1.A.4.C)
720
- if (!isFinalizing) {
721
- // Step (1.A.4.C.1)
722
- // Compute new average contribution/verification time.
723
- fullContributionTime = Number(verificationStartedAt) - Number(contributionStartedAt)
724
-
725
- const newAvgContributionComputationTime =
726
- avgContributionComputationTime > 0
727
- ? (avgContributionComputationTime + contributionComputationTime) / 2
728
- : contributionComputationTime
729
- const newAvgFullContributionTime =
730
- avgFullContributionTime > 0
731
- ? (avgFullContributionTime + fullContributionTime) / 2
732
- : fullContributionTime
733
- const newAvgVerifyCloudFunctionTime =
734
- avgVerifyCloudFunctionTime > 0
735
- ? (avgVerifyCloudFunctionTime + verifyCloudFunctionTime) / 2
736
- : verifyCloudFunctionTime
737
-
738
- // Prepare tx to update circuit average contribution/verification time.
739
- const updatedCircuitDoc = await getDocumentById(getCircuitsCollectionPath(ceremonyId), circuitId)
740
- const { waitingQueue: updatedWaitingQueue } = updatedCircuitDoc.data()!
741
- /// @dev this must happen only for valid contributions.
742
- batch.update(circuitDoc.ref, {
743
- avgTimings: {
744
- contributionComputation: isContributionValid
745
- ? newAvgContributionComputationTime
746
- : avgContributionComputationTime,
747
- fullContribution: isContributionValid ? newAvgFullContributionTime : avgFullContributionTime,
748
- verifyCloudFunction: isContributionValid
749
- ? newAvgVerifyCloudFunctionTime
750
- : avgVerifyCloudFunctionTime
751
- },
752
- waitingQueue: {
753
- ...updatedWaitingQueue,
754
- completedContributions: isContributionValid
755
- ? completedContributions + 1
756
- : completedContributions,
757
- failedContributions: isContributionValid ? failedContributions : failedContributions + 1
758
- },
759
- lastUpdated: getCurrentServerTimestampInMillis()
760
- })
761
- }
791
+ // Step (1).
792
+ if (isContributing || isFinalizing) {
793
+ // Prepare timer.
794
+ verificationTaskTimer.start()
762
795
 
763
- // Step (2).
764
- await batch.commit()
796
+ // Step (1.A.3.0).
797
+ if (isUsingVM) {
798
+ printLog(`Starting the VM mechanism`, LogLevel.DEBUG)
765
799
 
766
- printLog(
767
- `The contribution #${
768
- isFinalizing ? finalContributionIndex : lastZkeyIndex
769
- } of circuit ${circuitId} (ceremony ${ceremonyId}) has been verified as ${
770
- isContributionValid ? "valid" : "invalid"
771
- } for the participant ${participantDoc.id}`,
772
- LogLevel.DEBUG
773
- )
774
- }
800
+ // Prepare for VM execution.
801
+ let isVMRunning = false // true when the VM is up, otherwise false.
775
802
 
776
- // Step (1).
777
- if (isContributing || isFinalizing) {
778
- // Prepare timer.
779
- verificationTaskTimer.start()
803
+ // Step (1.A.3.1).
804
+ await startEC2Instance(ec2, vmInstanceId)
780
805
 
781
- // Step (1.A.3.0).
782
- if (isUsingVM) {
783
- printLog(`Starting the VM mechanism`, LogLevel.DEBUG)
806
+ await sleep(60000) // nb. wait for VM startup (1 mins + retry).
784
807
 
785
- // Prepare for VM execution.
786
- let isVMRunning = false // true when the VM is up, otherwise false.
808
+ // Check if the startup is running.
809
+ isVMRunning = await checkIfVMRunning(ec2, vmInstanceId)
787
810
 
788
- // Step (1.A.3.1).
789
- await startEC2Instance(ec2, vmInstanceId)
811
+ printLog(`VM running: ${isVMRunning}`, LogLevel.DEBUG)
790
812
 
791
- await sleep(60000) // nb. wait for VM startup (1 mins + retry).
813
+ // Step (1.A.3.2).
814
+ // Prepare.
815
+ const verificationCommand = vmContributionVerificationCommand(
816
+ bucketName,
817
+ lastZkeyStoragePath,
818
+ verificationTranscriptStoragePathAndFilename
819
+ )
792
820
 
793
- // Check if the startup is running.
794
- isVMRunning = await checkIfVMRunning(ec2, vmInstanceId)
821
+ // Run.
822
+ commandId = await runCommandUsingSSM(ssm, vmInstanceId, verificationCommand)
795
823
 
796
- printLog(`VM running: ${isVMRunning}`, LogLevel.DEBUG)
824
+ printLog(`Starting the execution of command ${commandId}`, LogLevel.DEBUG)
797
825
 
798
- // Step (1.A.3.2).
799
- // Prepare.
800
- const verificationCommand = vmContributionVerificationCommand(
801
- bucketName,
802
- lastZkeyStoragePath,
803
- verificationTranscriptStoragePathAndFilename
804
- )
826
+ // Step (1.A.3.3).
827
+ return await waitForVMCommandExecution(ssm, vmInstanceId, commandId)
828
+ .then(async () => {
829
+ // Command execution successfully completed.
830
+ printLog(`Command ${commandId} execution has been successfully completed`, LogLevel.DEBUG)
831
+ await completeVerification()
832
+ })
833
+ .catch((error: any) => {
834
+ // Command execution aborted.
835
+ printLog(`Command ${commandId} execution has been aborted - Error ${error}`, LogLevel.WARN)
805
836
 
806
- // Run.
807
- commandId = await runCommandUsingSSM(ssm, vmInstanceId, verificationCommand)
837
+ logAndThrowError(COMMON_ERRORS.CM_INVALID_COMMAND_EXECUTION)
838
+ })
839
+ }
808
840
 
809
- printLog(`Starting the execution of command ${commandId}`, LogLevel.DEBUG)
841
+ // CF approach.
842
+ printLog(`CF mechanism`, LogLevel.DEBUG)
810
843
 
811
- // Step (1.A.3.3).
812
- return waitForVMCommandExecution(ssm, vmInstanceId, commandId)
813
- .then(async () => {
814
- // Command execution successfully completed.
815
- printLog(`Command ${commandId} execution has been successfully completed`, LogLevel.DEBUG)
816
- await completeVerification()
817
- })
818
- .catch((error: any) => {
819
- // Command execution aborted.
820
- printLog(`Command ${commandId} execution has been aborted - Error ${error}`, LogLevel.DEBUG)
844
+ const potStoragePath = getPotStorageFilePath(files.potFilename)
845
+ const firstZkeyStoragePath = getZkeyStorageFilePath(prefix, `${prefix}_${genesisZkeyIndex}.zkey`)
846
+ printLog(`pot file: ${potStoragePath}`, LogLevel.DEBUG)
847
+ printLog(`zkey file: ${firstZkeyStoragePath}`, LogLevel.DEBUG)
848
+ // Prepare temporary file paths.
849
+ // (nb. these are needed to download the necessary artifacts for verification from AWS S3).
850
+ verificationTranscriptTemporaryLocalPath = createTemporaryLocalPath(
851
+ verificationTranscriptCompleteFilename
852
+ )
853
+ const potTempFilePath = createTemporaryLocalPath(`${circuitId}_${participantDoc.id}.pot`)
854
+ const firstZkeyTempFilePath = createTemporaryLocalPath(`${circuitId}_${participantDoc.id}_genesis.zkey`)
855
+ const lastZkeyTempFilePath = createTemporaryLocalPath(`${circuitId}_${participantDoc.id}_last.zkey`)
856
+ printLog(`pot file: ${potTempFilePath}`, LogLevel.DEBUG)
857
+ printLog(`firstZkey file: ${firstZkeyTempFilePath}`, LogLevel.DEBUG)
858
+ printLog(`last zkey file: ${lastZkeyTempFilePath}`, LogLevel.DEBUG)
859
+
860
+ // Create and populate transcript.
861
+ const transcriptLogger = createCustomLoggerForFile(verificationTranscriptTemporaryLocalPath)
862
+ transcriptLogger.info(
863
+ `${
864
+ isFinalizing ? `Final verification` : `Verification`
865
+ } transcript for ${prefix} circuit Phase 2 contribution.\n${
866
+ isFinalizing ? `Coordinator ` : `Contributor # ${Number(lastZkeyIndex)}`
867
+ } (${contributorOrCoordinatorIdentifier})\n`
868
+ )
821
869
 
822
- logAndThrowError(COMMON_ERRORS.CM_INVALID_COMMAND_EXECUTION)
823
- })
824
- }
870
+ // Step (1.A.2).
871
+ await downloadArtifactFromS3Bucket(bucketName, potStoragePath, potTempFilePath)
872
+ await downloadArtifactFromS3Bucket(bucketName, firstZkeyStoragePath, firstZkeyTempFilePath)
873
+ await downloadArtifactFromS3Bucket(bucketName, lastZkeyStoragePath, lastZkeyTempFilePath)
874
+
875
+ // Step (1.A.4).
876
+ isContributionValid = await zKey.verifyFromInit(
877
+ firstZkeyTempFilePath,
878
+ potTempFilePath,
879
+ lastZkeyTempFilePath,
880
+ transcriptLogger
881
+ )
825
882
 
826
- // CF approach.
827
- printLog(`CF mechanism`, LogLevel.DEBUG)
828
-
829
- const potStoragePath = getPotStorageFilePath(files.potFilename)
830
- const firstZkeyStoragePath = getZkeyStorageFilePath(prefix, `${prefix}_${genesisZkeyIndex}.zkey`)
831
- // Prepare temporary file paths.
832
- // (nb. these are needed to download the necessary artifacts for verification from AWS S3).
833
- verificationTranscriptTemporaryLocalPath = createTemporaryLocalPath(verificationTranscriptCompleteFilename)
834
- const potTempFilePath = createTemporaryLocalPath(`${circuitId}_${participantDoc.id}.pot`)
835
- const firstZkeyTempFilePath = createTemporaryLocalPath(`${circuitId}_${participantDoc.id}_genesis.zkey`)
836
- const lastZkeyTempFilePath = createTemporaryLocalPath(`${circuitId}_${participantDoc.id}_last.zkey`)
837
-
838
- // Create and populate transcript.
839
- const transcriptLogger = createCustomLoggerForFile(verificationTranscriptTemporaryLocalPath)
840
- transcriptLogger.info(
841
- `${
842
- isFinalizing ? `Final verification` : `Verification`
843
- } transcript for ${prefix} circuit Phase 2 contribution.\n${
844
- isFinalizing ? `Coordinator ` : `Contributor # ${Number(lastZkeyIndex)}`
845
- } (${contributorOrCoordinatorIdentifier})\n`
846
- )
883
+ await dumpLog(verificationTranscriptTemporaryLocalPath)
847
884
 
848
- // Step (1.A.2).
849
- await downloadArtifactFromS3Bucket(bucketName, potStoragePath, potTempFilePath)
850
- await downloadArtifactFromS3Bucket(bucketName, firstZkeyStoragePath, firstZkeyTempFilePath)
851
- await downloadArtifactFromS3Bucket(bucketName, lastZkeyStoragePath, lastZkeyTempFilePath)
852
-
853
- // Step (1.A.4).
854
- isContributionValid = await zKey.verifyFromInit(
855
- firstZkeyTempFilePath,
856
- potTempFilePath,
857
- lastZkeyTempFilePath,
858
- transcriptLogger
859
- )
885
+ // Compute contribution hash.
886
+ lastZkeyBlake2bHash = await blake512FromPath(lastZkeyTempFilePath)
860
887
 
861
- // Compute contribution hash.
862
- lastZkeyBlake2bHash = await blake512FromPath(lastZkeyTempFilePath)
888
+ // Free resources by unlinking temporary folders.
889
+ // Do not free-up verification transcript path here.
890
+ try {
891
+ fs.unlinkSync(potTempFilePath)
892
+ fs.unlinkSync(firstZkeyTempFilePath)
893
+ fs.unlinkSync(lastZkeyTempFilePath)
894
+ } catch (error: any) {
895
+ printLog(`Error while unlinking temporary files - Error ${error}`, LogLevel.WARN)
896
+ }
863
897
 
864
- // Free resources by unlinking temporary folders.
865
- // Do not free-up verification transcript path here.
866
- try {
867
- fs.unlinkSync(potTempFilePath)
868
- fs.unlinkSync(firstZkeyTempFilePath)
869
- fs.unlinkSync(lastZkeyTempFilePath)
870
- } catch (error: any) {
871
- printLog(`Error while unlinking temporary files - Error ${error}`, LogLevel.WARN)
898
+ await completeVerification()
872
899
  }
873
900
 
874
- await completeVerification()
901
+ return null
902
+ } catch (error: any) {
903
+ logAndThrowError(makeError("unknown", error))
904
+ return null
875
905
  }
876
906
  }
877
907
  )
@@ -884,7 +914,7 @@ export const verifycontribution = functionsV2.https.onCall(
884
914
  export const refreshParticipantAfterContributionVerification = functionsV1
885
915
  .region("europe-west1")
886
916
  .runWith({
887
- memory: "512MB"
917
+ memory: "1GB"
888
918
  })
889
919
  .firestore.document(
890
920
  `/${commonTerms.collections.ceremonies.name}/{ceremony}/${commonTerms.collections.circuits.name}/{circuit}/${commonTerms.collections.contributions.name}/{contributions}`
@@ -954,8 +984,8 @@ export const refreshParticipantAfterContributionVerification = functionsV1
954
984
  await batch.commit()
955
985
 
956
986
  printLog(
957
- `Participant ${participantId} refreshed after contribution ${createdContribution.id} - The participant was finalizing the ceremony ${isFinalizing}`,
958
- LogLevel.DEBUG
987
+ `Participant ${participantId} refreshed after contribution ${createdContribution.id} - The participant was finalizing the ceremony? ${isFinalizing}`,
988
+ LogLevel.INFO
959
989
  )
960
990
  })
961
991
 
@@ -967,7 +997,7 @@ export const refreshParticipantAfterContributionVerification = functionsV1
967
997
  export const finalizeCircuit = functionsV1
968
998
  .region("europe-west1")
969
999
  .runWith({
970
- memory: "512MB"
1000
+ memory: "1GB"
971
1001
  })
972
1002
  .https.onCall(async (data: FinalizeCircuitData, context: functionsV1.https.CallableContext) => {
973
1003
  if (!context.auth || !context.auth.token.coordinator) logAndThrowError(COMMON_ERRORS.CM_NOT_COORDINATOR_ROLE)