@devtion/backend 0.0.0-c749be4 → 0.0.0-e312890
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/dist/src/functions/index.js +561 -309
- package/dist/src/functions/index.mjs +562 -312
- package/dist/types/functions/bandada.d.ts +4 -0
- package/dist/types/functions/bandada.d.ts.map +1 -0
- package/dist/types/functions/circuit.d.ts.map +1 -1
- package/dist/types/functions/index.d.ts +2 -0
- package/dist/types/functions/index.d.ts.map +1 -1
- package/dist/types/functions/siwe.d.ts +4 -0
- package/dist/types/functions/siwe.d.ts.map +1 -0
- package/dist/types/lib/errors.d.ts +1 -1
- package/dist/types/lib/services.d.ts +7 -0
- package/dist/types/lib/services.d.ts.map +1 -1
- package/dist/types/types/index.d.ts +56 -0
- package/dist/types/types/index.d.ts.map +1 -1
- package/package.json +4 -3
- package/src/functions/bandada.ts +155 -0
- package/src/functions/ceremony.ts +5 -5
- package/src/functions/circuit.ts +373 -369
- package/src/functions/index.ts +2 -0
- package/src/functions/participant.ts +7 -7
- package/src/functions/siwe.ts +77 -0
- package/src/functions/storage.ts +6 -6
- package/src/functions/timeout.ts +2 -2
- package/src/functions/user.ts +4 -4
- package/src/lib/errors.ts +1 -1
- package/src/lib/services.ts +36 -0
- package/src/types/declarations.d.ts +1 -0
- package/src/types/index.ts +60 -0
package/src/functions/circuit.ts
CHANGED
|
@@ -44,7 +44,7 @@ import { EC2Client } from "@aws-sdk/client-ec2"
|
|
|
44
44
|
import { HttpsError } from "firebase-functions/v2/https"
|
|
45
45
|
import { FinalizeCircuitData, VerifyContributionData } from "../types/index"
|
|
46
46
|
import { LogLevel } from "../types/enums"
|
|
47
|
-
import { COMMON_ERRORS, logAndThrowError, printLog, SPECIFIC_ERRORS } from "../lib/errors"
|
|
47
|
+
import { COMMON_ERRORS, logAndThrowError, makeError, printLog, SPECIFIC_ERRORS } from "../lib/errors"
|
|
48
48
|
import {
|
|
49
49
|
createEC2Client,
|
|
50
50
|
createSSMClient,
|
|
@@ -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: "
|
|
315
|
+
memory: "1GB"
|
|
316
316
|
})
|
|
317
317
|
.firestore.document(
|
|
318
318
|
`${commonTerms.collections.ceremonies.name}/{ceremonyId}/${commonTerms.collections.participants.name}/{participantId}`
|
|
@@ -462,416 +462,420 @@ const checkIfVMRunning = async (ec2: EC2Client, vmInstanceId: string, attempts =
|
|
|
462
462
|
export const verifycontribution = functionsV2.https.onCall(
|
|
463
463
|
{ memory: "16GiB", timeoutSeconds: 3600, region: "europe-west1" },
|
|
464
464
|
async (request: functionsV2.https.CallableRequest<VerifyContributionData>): Promise<any> => {
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
if (
|
|
477
|
-
!process.env.CUSTOM_CONTRIBUTION_VERIFICATION_SOFTWARE_NAME ||
|
|
478
|
-
!process.env.CUSTOM_CONTRIBUTION_VERIFICATION_SOFTWARE_VERSION ||
|
|
479
|
-
!process.env.CUSTOM_CONTRIBUTION_VERIFICATION_SOFTWARE_COMMIT_HASH
|
|
480
|
-
)
|
|
481
|
-
logAndThrowError(COMMON_ERRORS.CM_WRONG_CONFIGURATION)
|
|
482
|
-
|
|
483
|
-
// Step (0).
|
|
484
|
-
|
|
485
|
-
// Prepare and start timer.
|
|
486
|
-
const verifyContributionTimer = new Timer({ label: commonTerms.cloudFunctionsNames.verifyContribution })
|
|
487
|
-
verifyContributionTimer.start()
|
|
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)
|
|
488
476
|
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
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).
|
|
485
|
+
|
|
486
|
+
// Prepare and start timer.
|
|
487
|
+
const verifyContributionTimer = new Timer({ label: commonTerms.cloudFunctionsNames.verifyContribution })
|
|
488
|
+
verifyContributionTimer.start()
|
|
489
|
+
|
|
490
|
+
// Get DB.
|
|
491
|
+
const firestore = admin.firestore()
|
|
492
|
+
// Prepare batch of txs.
|
|
493
|
+
const batch = firestore.batch()
|
|
494
|
+
|
|
495
|
+
// Extract data.
|
|
496
|
+
const { ceremonyId, circuitId, contributorOrCoordinatorIdentifier, bucketName } = request.data
|
|
497
|
+
const userId = request.auth?.uid
|
|
498
|
+
|
|
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!)
|
|
503
|
+
|
|
504
|
+
if (!ceremonyDoc.data() || !circuitDoc.data() || !participantDoc.data())
|
|
505
|
+
logAndThrowError(COMMON_ERRORS.CM_INEXISTENT_DOCUMENT_DATA)
|
|
506
|
+
|
|
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
|
|
493
521
|
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
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
|
+
)
|
|
497
563
|
|
|
498
|
-
|
|
499
|
-
const ceremonyDoc = await getDocumentById(commonTerms.collections.ceremonies.name, ceremonyId)
|
|
500
|
-
const circuitDoc = await getDocumentById(getCircuitsCollectionPath(ceremonyId), circuitId)
|
|
501
|
-
const participantDoc = await getDocumentById(getParticipantsCollectionPath(ceremonyId), userId!)
|
|
564
|
+
const verificationTaskTimer = new Timer({ label: `${ceremonyId}-${circuitId}-${participantDoc.id}` })
|
|
502
565
|
|
|
503
|
-
|
|
504
|
-
|
|
566
|
+
const completeVerification = async () => {
|
|
567
|
+
// Stop verification task timer.
|
|
568
|
+
printLog("Completing verification", LogLevel.DEBUG)
|
|
569
|
+
verificationTaskTimer.stop()
|
|
570
|
+
verifyCloudFunctionExecutionTime = verificationTaskTimer.ms()
|
|
505
571
|
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
const {
|
|
512
|
-
contributionComputation: avgContributionComputationTime,
|
|
513
|
-
fullContribution: avgFullContributionTime,
|
|
514
|
-
verifyCloudFunction: avgVerifyCloudFunctionTime
|
|
515
|
-
} = avgTimings
|
|
516
|
-
const { cfOrVm, vm } = verification
|
|
517
|
-
// we might not have it if the circuit is not using VM.
|
|
518
|
-
let vmInstanceId: string = ""
|
|
519
|
-
if (vm) vmInstanceId = vm.vmInstanceId
|
|
572
|
+
if (isUsingVM) {
|
|
573
|
+
// Create temporary path.
|
|
574
|
+
verificationTranscriptTemporaryLocalPath = createTemporaryLocalPath(
|
|
575
|
+
`${circuitId}_${participantDoc.id}.log`
|
|
576
|
+
)
|
|
520
577
|
|
|
521
|
-
|
|
522
|
-
const isFinalizing = state === CeremonyState.CLOSED && request.auth && request.auth.token.coordinator // true only when the coordinator verifies the final contributions.
|
|
523
|
-
const isContributing = status === ParticipantStatus.CONTRIBUTING
|
|
524
|
-
const isUsingVM = cfOrVm === CircuitContributionVerificationMechanism.VM && !!vmInstanceId
|
|
525
|
-
|
|
526
|
-
// Prepare state.
|
|
527
|
-
let isContributionValid = false
|
|
528
|
-
let verifyCloudFunctionExecutionTime = 0 // time spent while executing the verify contribution cloud function.
|
|
529
|
-
let verifyCloudFunctionTime = 0 // time spent while executing the core business logic of this cloud function.
|
|
530
|
-
let fullContributionTime = 0 // time spent while doing non-verification contributions tasks (download, compute, upload).
|
|
531
|
-
let contributionComputationTime = 0 // time spent while computing the contribution.
|
|
532
|
-
let lastZkeyBlake2bHash: string = "" // the Blake2B hash of the last zKey.
|
|
533
|
-
let verificationTranscriptTemporaryLocalPath: string = "" // the local temporary path for the verification transcript.
|
|
534
|
-
let transcriptBlake2bHash: string = "" // the Blake2B hash of the verification transcript.
|
|
535
|
-
let commandId: string = "" // the unique identifier of the VM command.
|
|
536
|
-
|
|
537
|
-
// Derive necessary data.
|
|
538
|
-
const lastZkeyIndex = formatZkeyIndex(completedContributions + 1)
|
|
539
|
-
const verificationTranscriptCompleteFilename = `${prefix}_${
|
|
540
|
-
isFinalizing
|
|
541
|
-
? `${contributorOrCoordinatorIdentifier}_${finalContributionIndex}_verification_transcript.log`
|
|
542
|
-
: `${lastZkeyIndex}_${contributorOrCoordinatorIdentifier}_verification_transcript.log`
|
|
543
|
-
}`
|
|
544
|
-
|
|
545
|
-
const lastZkeyFilename = `${prefix}_${isFinalizing ? finalContributionIndex : lastZkeyIndex}.zkey`
|
|
546
|
-
|
|
547
|
-
// Prepare state for VM verification (if needed).
|
|
548
|
-
const ec2 = await createEC2Client()
|
|
549
|
-
const ssm = await createSSMClient()
|
|
550
|
-
|
|
551
|
-
// Step (1.A.1).
|
|
552
|
-
// Get storage paths.
|
|
553
|
-
const verificationTranscriptStoragePathAndFilename = getTranscriptStorageFilePath(
|
|
554
|
-
prefix,
|
|
555
|
-
verificationTranscriptCompleteFilename
|
|
556
|
-
)
|
|
557
|
-
// the zKey storage path is required to be sent to the VM api
|
|
558
|
-
const lastZkeyStoragePath = getZkeyStorageFilePath(
|
|
559
|
-
prefix,
|
|
560
|
-
`${prefix}_${isFinalizing ? finalContributionIndex : lastZkeyIndex}.zkey`
|
|
561
|
-
)
|
|
578
|
+
await sleep(1000) // wait 1s for file creation.
|
|
562
579
|
|
|
563
|
-
|
|
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
|
+
)
|
|
564
587
|
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
printLog("Completing verification", LogLevel.DEBUG)
|
|
568
|
-
verificationTaskTimer.stop()
|
|
569
|
-
verifyCloudFunctionExecutionTime = verificationTaskTimer.ms()
|
|
588
|
+
// Read the verification trascript and validate data by checking for core info ("ZKey Ok!").
|
|
589
|
+
const content = fs.readFileSync(verificationTranscriptTemporaryLocalPath, "utf-8")
|
|
570
590
|
|
|
571
|
-
|
|
572
|
-
// Create temporary path.
|
|
573
|
-
verificationTranscriptTemporaryLocalPath = createTemporaryLocalPath(
|
|
574
|
-
`${circuitId}_${participantDoc.id}.log`
|
|
575
|
-
)
|
|
591
|
+
if (content.includes("ZKey Ok!")) isContributionValid = true
|
|
576
592
|
|
|
577
|
-
|
|
593
|
+
// If the contribution is valid, then format and store the trascript.
|
|
594
|
+
if (isContributionValid) {
|
|
595
|
+
// eslint-disable-next-line no-control-regex
|
|
596
|
+
const updated = content.replace(/\x1b[[0-9;]*m/g, "")
|
|
578
597
|
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
bucketName,
|
|
583
|
-
verificationTranscriptStoragePathAndFilename,
|
|
584
|
-
verificationTranscriptTemporaryLocalPath
|
|
585
|
-
)
|
|
598
|
+
fs.writeFileSync(verificationTranscriptTemporaryLocalPath, updated)
|
|
599
|
+
}
|
|
600
|
+
}
|
|
586
601
|
|
|
587
|
-
|
|
588
|
-
const content = fs.readFileSync(verificationTranscriptTemporaryLocalPath, "utf-8")
|
|
602
|
+
printLog(`The contribution has been verified - Result ${isContributionValid}`, LogLevel.DEBUG)
|
|
589
603
|
|
|
590
|
-
|
|
604
|
+
// Create a new contribution document.
|
|
605
|
+
const contributionDoc = await firestore
|
|
606
|
+
.collection(getContributionsCollectionPath(ceremonyId, circuitId))
|
|
607
|
+
.doc()
|
|
608
|
+
.get()
|
|
591
609
|
|
|
592
|
-
//
|
|
610
|
+
// Step (1.A.4).
|
|
593
611
|
if (isContributionValid) {
|
|
594
|
-
//
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
612
|
+
// Sleep ~3 seconds to wait for verification transcription.
|
|
613
|
+
await sleep(3000)
|
|
614
|
+
|
|
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)
|
|
619
|
+
|
|
620
|
+
const hashRegex = /[a-fA-F0-9]{64}/
|
|
621
|
+
const match = lastZkeyBlake2bHash.match(hashRegex)!
|
|
622
|
+
|
|
623
|
+
lastZkeyBlake2bHash = match.at(0)!
|
|
624
|
+
|
|
625
|
+
// re upload the formatted verification transcript
|
|
626
|
+
await uploadFileToBucket(
|
|
627
|
+
bucketName,
|
|
628
|
+
verificationTranscriptStoragePathAndFilename,
|
|
629
|
+
verificationTranscriptTemporaryLocalPath,
|
|
630
|
+
true
|
|
631
|
+
)
|
|
632
|
+
} 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
|
+
)
|
|
641
|
+
}
|
|
602
642
|
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
.collection(getContributionsCollectionPath(ceremonyId, circuitId))
|
|
606
|
-
.doc()
|
|
607
|
-
.get()
|
|
643
|
+
// Compute verification transcript hash.
|
|
644
|
+
transcriptBlake2bHash = await blake512FromPath(verificationTranscriptTemporaryLocalPath)
|
|
608
645
|
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
// Sleep ~3 seconds to wait for verification transcription.
|
|
612
|
-
await sleep(3000)
|
|
646
|
+
// Free resources by unlinking transcript temporary file.
|
|
647
|
+
fs.unlinkSync(verificationTranscriptTemporaryLocalPath)
|
|
613
648
|
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
const hashRegex = /[a-fA-F0-9]{64}/
|
|
620
|
-
const match = lastZkeyBlake2bHash.match(hashRegex)!
|
|
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
|
|
653
|
+
)
|
|
621
654
|
|
|
622
|
-
|
|
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
|
+
})
|
|
623
684
|
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
bucketName,
|
|
627
|
-
verificationTranscriptStoragePathAndFilename,
|
|
628
|
-
verificationTranscriptTemporaryLocalPath,
|
|
629
|
-
true
|
|
630
|
-
)
|
|
685
|
+
verifyContributionTimer.stop()
|
|
686
|
+
verifyCloudFunctionTime = verifyContributionTimer.ms()
|
|
631
687
|
} else {
|
|
632
|
-
//
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
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
|
+
})
|
|
640
706
|
}
|
|
641
707
|
|
|
642
|
-
//
|
|
643
|
-
|
|
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
|
+
}
|
|
644
762
|
|
|
645
|
-
//
|
|
646
|
-
|
|
763
|
+
// Step (2).
|
|
764
|
+
await batch.commit()
|
|
647
765
|
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
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
|
|
652
773
|
)
|
|
653
|
-
|
|
654
|
-
/// @dev (there must be only one contribution with an empty 'doc' field).
|
|
655
|
-
if (participantContributions.length !== 1)
|
|
656
|
-
logAndThrowError(SPECIFIC_ERRORS.SE_VERIFICATION_NO_PARTICIPANT_CONTRIBUTION_DATA)
|
|
657
|
-
|
|
658
|
-
// Get contribution computation time.
|
|
659
|
-
contributionComputationTime = contributions.at(0).computationTime
|
|
660
|
-
|
|
661
|
-
// Step (1.A.4.A.2).
|
|
662
|
-
batch.create(contributionDoc.ref, {
|
|
663
|
-
participantId: participantDoc.id,
|
|
664
|
-
contributionComputationTime,
|
|
665
|
-
verificationComputationTime: verifyCloudFunctionExecutionTime,
|
|
666
|
-
zkeyIndex: isFinalizing ? finalContributionIndex : lastZkeyIndex,
|
|
667
|
-
files: {
|
|
668
|
-
transcriptFilename: verificationTranscriptCompleteFilename,
|
|
669
|
-
lastZkeyFilename,
|
|
670
|
-
transcriptStoragePath: verificationTranscriptStoragePathAndFilename,
|
|
671
|
-
lastZkeyStoragePath,
|
|
672
|
-
transcriptBlake2bHash,
|
|
673
|
-
lastZkeyBlake2bHash
|
|
674
|
-
},
|
|
675
|
-
verificationSoftware: {
|
|
676
|
-
name: String(process.env.CUSTOM_CONTRIBUTION_VERIFICATION_SOFTWARE_NAME),
|
|
677
|
-
version: String(process.env.CUSTOM_CONTRIBUTION_VERIFICATION_SOFTWARE_VERSION),
|
|
678
|
-
commitHash: String(process.env.CUSTOM_CONTRIBUTION_VERIFICATION_SOFTWARE_COMMIT_HASH)
|
|
679
|
-
},
|
|
680
|
-
valid: isContributionValid,
|
|
681
|
-
lastUpdated: getCurrentServerTimestampInMillis()
|
|
682
|
-
})
|
|
683
|
-
|
|
684
|
-
verifyContributionTimer.stop()
|
|
685
|
-
verifyCloudFunctionTime = verifyContributionTimer.ms()
|
|
686
|
-
} else {
|
|
687
|
-
// Step (1.A.4.B).
|
|
688
|
-
|
|
689
|
-
// Free-up storage by deleting invalid contribution.
|
|
690
|
-
await deleteObject(bucketName, lastZkeyStoragePath)
|
|
691
|
-
|
|
692
|
-
// Step (1.A.4.B.1).
|
|
693
|
-
batch.create(contributionDoc.ref, {
|
|
694
|
-
participantId: participantDoc.id,
|
|
695
|
-
verificationComputationTime: verifyCloudFunctionExecutionTime,
|
|
696
|
-
zkeyIndex: isFinalizing ? finalContributionIndex : lastZkeyIndex,
|
|
697
|
-
verificationSoftware: {
|
|
698
|
-
name: String(process.env.CUSTOM_CONTRIBUTION_VERIFICATION_SOFTWARE_NAME),
|
|
699
|
-
version: String(process.env.CUSTOM_CONTRIBUTION_VERIFICATION_SOFTWARE_VERSION),
|
|
700
|
-
commitHash: String(process.env.CUSTOM_CONTRIBUTION_VERIFICATION_SOFTWARE_COMMIT_HASH)
|
|
701
|
-
},
|
|
702
|
-
valid: isContributionValid,
|
|
703
|
-
lastUpdated: getCurrentServerTimestampInMillis()
|
|
704
|
-
})
|
|
705
774
|
}
|
|
706
775
|
|
|
707
|
-
//
|
|
708
|
-
if (
|
|
709
|
-
//
|
|
710
|
-
|
|
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
|
-
}
|
|
718
|
-
// Step (1.A.4.C)
|
|
719
|
-
if (!isFinalizing) {
|
|
720
|
-
// Step (1.A.4.C.1)
|
|
721
|
-
// Compute new average contribution/verification time.
|
|
722
|
-
fullContributionTime = Number(verificationStartedAt) - Number(contributionStartedAt)
|
|
723
|
-
|
|
724
|
-
const newAvgContributionComputationTime =
|
|
725
|
-
avgContributionComputationTime > 0
|
|
726
|
-
? (avgContributionComputationTime + contributionComputationTime) / 2
|
|
727
|
-
: contributionComputationTime
|
|
728
|
-
const newAvgFullContributionTime =
|
|
729
|
-
avgFullContributionTime > 0
|
|
730
|
-
? (avgFullContributionTime + fullContributionTime) / 2
|
|
731
|
-
: fullContributionTime
|
|
732
|
-
const newAvgVerifyCloudFunctionTime =
|
|
733
|
-
avgVerifyCloudFunctionTime > 0
|
|
734
|
-
? (avgVerifyCloudFunctionTime + verifyCloudFunctionTime) / 2
|
|
735
|
-
: verifyCloudFunctionTime
|
|
736
|
-
|
|
737
|
-
// Prepare tx to update circuit average contribution/verification time.
|
|
738
|
-
const updatedCircuitDoc = await getDocumentById(getCircuitsCollectionPath(ceremonyId), circuitId)
|
|
739
|
-
const { waitingQueue: updatedWaitingQueue } = updatedCircuitDoc.data()!
|
|
740
|
-
/// @dev this must happen only for valid contributions.
|
|
741
|
-
batch.update(circuitDoc.ref, {
|
|
742
|
-
avgTimings: {
|
|
743
|
-
contributionComputation: isContributionValid
|
|
744
|
-
? newAvgContributionComputationTime
|
|
745
|
-
: avgContributionComputationTime,
|
|
746
|
-
fullContribution: isContributionValid ? newAvgFullContributionTime : avgFullContributionTime,
|
|
747
|
-
verifyCloudFunction: isContributionValid
|
|
748
|
-
? newAvgVerifyCloudFunctionTime
|
|
749
|
-
: avgVerifyCloudFunctionTime
|
|
750
|
-
},
|
|
751
|
-
waitingQueue: {
|
|
752
|
-
...updatedWaitingQueue,
|
|
753
|
-
completedContributions: isContributionValid
|
|
754
|
-
? completedContributions + 1
|
|
755
|
-
: completedContributions,
|
|
756
|
-
failedContributions: isContributionValid ? failedContributions : failedContributions + 1
|
|
757
|
-
},
|
|
758
|
-
lastUpdated: getCurrentServerTimestampInMillis()
|
|
759
|
-
})
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
// Step (2).
|
|
763
|
-
await batch.commit()
|
|
764
|
-
|
|
765
|
-
printLog(
|
|
766
|
-
`The contribution #${
|
|
767
|
-
isFinalizing ? finalContributionIndex : lastZkeyIndex
|
|
768
|
-
} of circuit ${circuitId} (ceremony ${ceremonyId}) has been verified as ${
|
|
769
|
-
isContributionValid ? "valid" : "invalid"
|
|
770
|
-
} for the participant ${participantDoc.id}`,
|
|
771
|
-
LogLevel.DEBUG
|
|
772
|
-
)
|
|
773
|
-
}
|
|
776
|
+
// Step (1).
|
|
777
|
+
if (isContributing || isFinalizing) {
|
|
778
|
+
// Prepare timer.
|
|
779
|
+
verificationTaskTimer.start()
|
|
774
780
|
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
verificationTaskTimer.start()
|
|
781
|
+
// Step (1.A.3.0).
|
|
782
|
+
if (isUsingVM) {
|
|
783
|
+
printLog(`Starting the VM mechanism`, LogLevel.DEBUG)
|
|
779
784
|
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
printLog(`Starting the VM mechanism`, LogLevel.DEBUG)
|
|
785
|
+
// Prepare for VM execution.
|
|
786
|
+
let isVMRunning = false // true when the VM is up, otherwise false.
|
|
783
787
|
|
|
784
|
-
|
|
785
|
-
|
|
788
|
+
// Step (1.A.3.1).
|
|
789
|
+
await startEC2Instance(ec2, vmInstanceId)
|
|
786
790
|
|
|
787
|
-
|
|
788
|
-
await startEC2Instance(ec2, vmInstanceId)
|
|
791
|
+
await sleep(60000) // nb. wait for VM startup (1 mins + retry).
|
|
789
792
|
|
|
790
|
-
|
|
793
|
+
// Check if the startup is running.
|
|
794
|
+
isVMRunning = await checkIfVMRunning(ec2, vmInstanceId)
|
|
791
795
|
|
|
792
|
-
|
|
793
|
-
isVMRunning = await checkIfVMRunning(ec2, vmInstanceId)
|
|
796
|
+
printLog(`VM running: ${isVMRunning}`, LogLevel.DEBUG)
|
|
794
797
|
|
|
795
|
-
|
|
798
|
+
// Step (1.A.3.2).
|
|
799
|
+
// Prepare.
|
|
800
|
+
const verificationCommand = vmContributionVerificationCommand(
|
|
801
|
+
bucketName,
|
|
802
|
+
lastZkeyStoragePath,
|
|
803
|
+
verificationTranscriptStoragePathAndFilename
|
|
804
|
+
)
|
|
796
805
|
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
const verificationCommand = vmContributionVerificationCommand(
|
|
800
|
-
bucketName,
|
|
801
|
-
lastZkeyStoragePath,
|
|
802
|
-
verificationTranscriptStoragePathAndFilename
|
|
803
|
-
)
|
|
806
|
+
// Run.
|
|
807
|
+
commandId = await runCommandUsingSSM(ssm, vmInstanceId, verificationCommand)
|
|
804
808
|
|
|
805
|
-
|
|
806
|
-
commandId = await runCommandUsingSSM(ssm, vmInstanceId, verificationCommand)
|
|
809
|
+
printLog(`Starting the execution of command ${commandId}`, LogLevel.DEBUG)
|
|
807
810
|
|
|
808
|
-
|
|
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)
|
|
809
821
|
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
// Command execution successfully completed.
|
|
814
|
-
printLog(`Command ${commandId} execution has been successfully completed`, LogLevel.DEBUG)
|
|
815
|
-
await completeVerification()
|
|
816
|
-
})
|
|
817
|
-
.catch((error: any) => {
|
|
818
|
-
// Command execution aborted.
|
|
819
|
-
printLog(`Command ${commandId} execution has been aborted - Error ${error}`, LogLevel.DEBUG)
|
|
822
|
+
logAndThrowError(COMMON_ERRORS.CM_INVALID_COMMAND_EXECUTION)
|
|
823
|
+
})
|
|
824
|
+
}
|
|
820
825
|
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
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
|
+
)
|
|
824
847
|
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
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
|
-
)
|
|
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
|
+
)
|
|
846
860
|
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
await downloadArtifactFromS3Bucket(bucketName, firstZkeyStoragePath, firstZkeyTempFilePath)
|
|
850
|
-
await downloadArtifactFromS3Bucket(bucketName, lastZkeyStoragePath, lastZkeyTempFilePath)
|
|
851
|
-
|
|
852
|
-
// Step (1.A.4).
|
|
853
|
-
isContributionValid = await zKey.verifyFromInit(
|
|
854
|
-
firstZkeyTempFilePath,
|
|
855
|
-
potTempFilePath,
|
|
856
|
-
lastZkeyTempFilePath,
|
|
857
|
-
transcriptLogger
|
|
858
|
-
)
|
|
861
|
+
// Compute contribution hash.
|
|
862
|
+
lastZkeyBlake2bHash = await blake512FromPath(lastZkeyTempFilePath)
|
|
859
863
|
|
|
860
|
-
|
|
861
|
-
|
|
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)
|
|
872
|
+
}
|
|
862
873
|
|
|
863
|
-
|
|
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)
|
|
874
|
+
await completeVerification()
|
|
871
875
|
}
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
}
|
|
876
|
+
} catch (error: any) {
|
|
877
|
+
logAndThrowError(makeError("unknown", error))
|
|
878
|
+
}
|
|
875
879
|
}
|
|
876
880
|
)
|
|
877
881
|
|
|
@@ -883,7 +887,7 @@ export const verifycontribution = functionsV2.https.onCall(
|
|
|
883
887
|
export const refreshParticipantAfterContributionVerification = functionsV1
|
|
884
888
|
.region("europe-west1")
|
|
885
889
|
.runWith({
|
|
886
|
-
memory: "
|
|
890
|
+
memory: "1GB"
|
|
887
891
|
})
|
|
888
892
|
.firestore.document(
|
|
889
893
|
`/${commonTerms.collections.ceremonies.name}/{ceremony}/${commonTerms.collections.circuits.name}/{circuit}/${commonTerms.collections.contributions.name}/{contributions}`
|
|
@@ -966,7 +970,7 @@ export const refreshParticipantAfterContributionVerification = functionsV1
|
|
|
966
970
|
export const finalizeCircuit = functionsV1
|
|
967
971
|
.region("europe-west1")
|
|
968
972
|
.runWith({
|
|
969
|
-
memory: "
|
|
973
|
+
memory: "1GB"
|
|
970
974
|
})
|
|
971
975
|
.https.onCall(async (data: FinalizeCircuitData, context: functionsV1.https.CallableContext) => {
|
|
972
976
|
if (!context.auth || !context.auth.token.coordinator) logAndThrowError(COMMON_ERRORS.CM_NOT_COORDINATOR_ROLE)
|