@devtion/backend 0.0.0-004e6ad → 0.0.0-08cd76b
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 +426 -392
- package/dist/src/functions/index.mjs +427 -393
- package/dist/{types → src/functions/types}/functions/bandada.d.ts.map +1 -1
- package/dist/{types → src/functions/types}/functions/ceremony.d.ts.map +1 -1
- package/dist/{types → src/functions/types}/functions/circuit.d.ts.map +1 -1
- package/dist/{types → src/functions/types}/functions/storage.d.ts.map +1 -1
- package/dist/{types → src/functions/types}/lib/errors.d.ts +1 -0
- package/dist/src/functions/types/lib/errors.d.ts.map +1 -0
- package/dist/{types → src/functions/types}/lib/services.d.ts.map +1 -1
- package/dist/src/functions/types/lib/utils.d.ts.map +1 -0
- package/package.json +6 -6
- package/src/functions/bandada.ts +96 -97
- package/src/functions/ceremony.ts +7 -3
- package/src/functions/circuit.ts +408 -377
- package/src/functions/storage.ts +1 -0
- package/src/functions/timeout.ts +9 -9
- package/src/lib/errors.ts +5 -0
- package/dist/types/lib/errors.d.ts.map +0 -1
- package/dist/types/lib/utils.d.ts.map +0 -1
- /package/dist/{types → src/functions/types}/functions/bandada.d.ts +0 -0
- /package/dist/{types → src/functions/types}/functions/ceremony.d.ts +0 -0
- /package/dist/{types → src/functions/types}/functions/circuit.d.ts +0 -0
- /package/dist/{types → src/functions/types}/functions/index.d.ts +0 -0
- /package/dist/{types → src/functions/types}/functions/index.d.ts.map +0 -0
- /package/dist/{types → src/functions/types}/functions/participant.d.ts +0 -0
- /package/dist/{types → src/functions/types}/functions/participant.d.ts.map +0 -0
- /package/dist/{types → src/functions/types}/functions/siwe.d.ts +0 -0
- /package/dist/{types → src/functions/types}/functions/siwe.d.ts.map +0 -0
- /package/dist/{types → src/functions/types}/functions/storage.d.ts +0 -0
- /package/dist/{types → src/functions/types}/functions/timeout.d.ts +0 -0
- /package/dist/{types → src/functions/types}/functions/timeout.d.ts.map +0 -0
- /package/dist/{types → src/functions/types}/functions/user.d.ts +0 -0
- /package/dist/{types → src/functions/types}/functions/user.d.ts.map +0 -0
- /package/dist/{types → src/functions/types}/lib/services.d.ts +0 -0
- /package/dist/{types → src/functions/types}/lib/utils.d.ts +0 -0
- /package/dist/{types → src/functions/types}/types/enums.d.ts +0 -0
- /package/dist/{types → src/functions/types}/types/enums.d.ts.map +0 -0
- /package/dist/{types → src/functions/types}/types/index.d.ts +0 -0
- /package/dist/{types → src/functions/types}/types/index.d.ts.map +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @module @p0tion/backend
|
|
3
|
-
* @version 1.2.
|
|
3
|
+
* @version 1.2.8
|
|
4
4
|
* @file MPC Phase 2 backend for Firebase services management
|
|
5
5
|
* @copyright Ethereum Foundation 2022
|
|
6
6
|
* @license MIT
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import admin from 'firebase-admin';
|
|
10
10
|
import * as functions from 'firebase-functions';
|
|
11
11
|
import dotenv from 'dotenv';
|
|
12
|
-
import { getCircuitsCollectionPath, getTimeoutsCollectionPath, commonTerms, finalContributionIndex, getContributionsCollectionPath, githubReputation, getBucketName, vmBootstrapCommand, vmDependenciesAndCacheArtifactsCommand, vmBootstrapScriptFilename, computeDiskSizeForVM, createEC2Instance, getParticipantsCollectionPath, terminateEC2Instance, formatZkeyIndex, getTranscriptStorageFilePath, getZkeyStorageFilePath, startEC2Instance, vmContributionVerificationCommand, runCommandUsingSSM, getPotStorageFilePath, genesisZkeyIndex, createCustomLoggerForFile,
|
|
12
|
+
import { getCircuitsCollectionPath, getTimeoutsCollectionPath, commonTerms, finalContributionIndex, getContributionsCollectionPath, githubReputation, getBucketName, vmBootstrapCommand, vmDependenciesAndCacheArtifactsCommand, vmBootstrapScriptFilename, computeDiskSizeForVM, createEC2Instance, getParticipantsCollectionPath, terminateEC2Instance, formatZkeyIndex, getTranscriptStorageFilePath, getZkeyStorageFilePath, retrieveCommandOutput, blake512FromPath, stopEC2Instance, startEC2Instance, vmContributionVerificationCommand, runCommandUsingSSM, getPotStorageFilePath, genesisZkeyIndex, createCustomLoggerForFile, getVerificationKeyStorageFilePath, getVerifierContractStorageFilePath, computeSHA256ToHex, checkIfRunning, verificationKeyAcronym, verifierSmartContractAcronym, retrieveCommandStatus } from '@p0tion/actions';
|
|
13
13
|
import { encode } from 'html-entities';
|
|
14
14
|
import { Timestamp, FieldValue } from 'firebase-admin/firestore';
|
|
15
15
|
import { S3Client, GetObjectCommand, PutObjectCommand, DeleteObjectCommand, HeadBucketCommand, CreateBucketCommand, PutPublicAccessBlockCommand, PutBucketCorsCommand, HeadObjectCommand, CreateMultipartUploadCommand, UploadPartCommand, CompleteMultipartUploadCommand } from '@aws-sdk/client-s3';
|
|
@@ -125,7 +125,8 @@ const SPECIFIC_ERRORS = {
|
|
|
125
125
|
SE_VM_TIMEDOUT_COMMAND_EXECUTION: makeError("deadline-exceeded", "VM command execution took too long and has been timed-out", "Please, contact the coordinator if this error persists."),
|
|
126
126
|
SE_VM_CANCELLED_COMMAND_EXECUTION: makeError("cancelled", "VM command execution has been cancelled", "Please, contact the coordinator if this error persists."),
|
|
127
127
|
SE_VM_DELAYED_COMMAND_EXECUTION: makeError("unavailable", "VM command execution has been delayed since there were no available instance at the moment", "Please, contact the coordinator if this error persists."),
|
|
128
|
-
SE_VM_UNKNOWN_COMMAND_STATUS: makeError("unavailable", "VM command execution has failed due to an unknown status code", "Please, contact the coordinator if this error persists.")
|
|
128
|
+
SE_VM_UNKNOWN_COMMAND_STATUS: makeError("unavailable", "VM command execution has failed due to an unknown status code", "Please, contact the coordinator if this error persists."),
|
|
129
|
+
WRONG_BUCKET_NAME: makeError("invalid-argument", "The provided bucket name is not valid.", "Bucket names must be between 3 and 63 characters long, can only contain lowercase letters, numbers, and hyphens, and must start and end with a letter or number.")
|
|
129
130
|
};
|
|
130
131
|
/**
|
|
131
132
|
* A set of common errors.
|
|
@@ -746,7 +747,9 @@ const setupCeremony = functions
|
|
|
746
747
|
// The VM unique identifier (if any).
|
|
747
748
|
let vmInstanceId = "";
|
|
748
749
|
// Get a new circuit document.
|
|
749
|
-
const
|
|
750
|
+
const ccp = getCircuitsCollectionPath(ceremonyDoc.ref.id);
|
|
751
|
+
printLog(`CircuitsCollectionPath = ${ccp}`, LogLevel.DEBUG);
|
|
752
|
+
const circuitDoc = await firestore.collection(ccp).doc().get();
|
|
750
753
|
// Check if using the VM approach for contribution verification.
|
|
751
754
|
if (circuit.verification.cfOrVm === "VM" /* CircuitContributionVerificationMechanism.VM */) {
|
|
752
755
|
// VM command to be run at the startup.
|
|
@@ -783,12 +786,14 @@ const setupCeremony = functions
|
|
|
783
786
|
}
|
|
784
787
|
// Encode circuit data.
|
|
785
788
|
const encodedCircuit = htmlEncodeCircuitData(circuit);
|
|
789
|
+
printLog(`writing circuit data...`, LogLevel.DEBUG);
|
|
786
790
|
// Prepare tx to write circuit data.
|
|
787
791
|
batch.create(circuitDoc.ref, {
|
|
788
792
|
...encodedCircuit,
|
|
789
793
|
lastUpdated: getCurrentServerTimestampInMillis()
|
|
790
794
|
});
|
|
791
795
|
}
|
|
796
|
+
printLog(`Done handling circuits...`, LogLevel.DEBUG);
|
|
792
797
|
// Send txs in a batch (to avoid race conditions).
|
|
793
798
|
await batch.commit();
|
|
794
799
|
printLog(`Setup completed for ceremony ${ceremonyDoc.id}`, LogLevel.DEBUG);
|
|
@@ -801,7 +806,7 @@ const setupCeremony = functions
|
|
|
801
806
|
const initEmptyWaitingQueueForCircuit = functions
|
|
802
807
|
.region("europe-west1")
|
|
803
808
|
.runWith({
|
|
804
|
-
memory: "
|
|
809
|
+
memory: "1GB"
|
|
805
810
|
})
|
|
806
811
|
.firestore.document(`/${commonTerms.collections.ceremonies.name}/{ceremony}/${commonTerms.collections.circuits.name}/{circuit}`)
|
|
807
812
|
.onCreate(async (doc) => {
|
|
@@ -833,7 +838,7 @@ const initEmptyWaitingQueueForCircuit = functions
|
|
|
833
838
|
const finalizeCeremony = functions
|
|
834
839
|
.region("europe-west1")
|
|
835
840
|
.runWith({
|
|
836
|
-
memory: "
|
|
841
|
+
memory: "1GB"
|
|
837
842
|
})
|
|
838
843
|
.https.onCall(async (data, context) => {
|
|
839
844
|
if (!context.auth || !context.auth.token.coordinator)
|
|
@@ -1310,7 +1315,7 @@ const coordinate = async (participant, circuit, isSingleParticipantCoordination,
|
|
|
1310
1315
|
if (isSingleParticipantCoordination) {
|
|
1311
1316
|
// Scenario (A).
|
|
1312
1317
|
if (emptyWaitingQueue) {
|
|
1313
|
-
printLog(`Coordinate - executing scenario A - emptyWaitingQueue`, LogLevel.
|
|
1318
|
+
printLog(`Coordinate - executing scenario A - emptyWaitingQueue`, LogLevel.INFO);
|
|
1314
1319
|
// Update.
|
|
1315
1320
|
newCurrentContributorId = participant.id;
|
|
1316
1321
|
newParticipantStatus = "CONTRIBUTING" /* ParticipantStatus.CONTRIBUTING */;
|
|
@@ -1319,14 +1324,14 @@ const coordinate = async (participant, circuit, isSingleParticipantCoordination,
|
|
|
1319
1324
|
}
|
|
1320
1325
|
// Scenario (A).
|
|
1321
1326
|
else if (participantResumingAfterTimeoutExpiration) {
|
|
1322
|
-
printLog(`Coordinate - executing scenario A - single - participantResumingAfterTimeoutExpiration`, LogLevel.
|
|
1327
|
+
printLog(`Coordinate - executing scenario A - single - participantResumingAfterTimeoutExpiration`, LogLevel.INFO);
|
|
1323
1328
|
newParticipantStatus = "CONTRIBUTING" /* ParticipantStatus.CONTRIBUTING */;
|
|
1324
1329
|
newContributionStep = "DOWNLOADING" /* ParticipantContributionStep.DOWNLOADING */;
|
|
1325
1330
|
newCurrentContributorId = participant.id;
|
|
1326
1331
|
}
|
|
1327
1332
|
// Scenario (B).
|
|
1328
1333
|
else if (participantIsNotCurrentContributor) {
|
|
1329
|
-
printLog(`Coordinate - executing scenario B - single - participantIsNotCurrentContributor`, LogLevel.
|
|
1334
|
+
printLog(`Coordinate - executing scenario B - single - participantIsNotCurrentContributor`, LogLevel.INFO);
|
|
1330
1335
|
newCurrentContributorId = currentContributor;
|
|
1331
1336
|
newParticipantStatus = "WAITING" /* ParticipantStatus.WAITING */;
|
|
1332
1337
|
newContributors.push(participant.id);
|
|
@@ -1345,7 +1350,7 @@ const coordinate = async (participant, circuit, isSingleParticipantCoordination,
|
|
|
1345
1350
|
});
|
|
1346
1351
|
}
|
|
1347
1352
|
else if (participantIsCurrentContributor && participantCompletedOneOrAllContributions && !!ceremonyId) {
|
|
1348
|
-
printLog(`Coordinate - executing scenario C - multi - participantIsCurrentContributor && participantCompletedOneOrAllContributions`, LogLevel.
|
|
1353
|
+
printLog(`Coordinate - executing scenario C - multi - participantIsCurrentContributor && participantCompletedOneOrAllContributions`, LogLevel.INFO);
|
|
1349
1354
|
newParticipantStatus = "CONTRIBUTING" /* ParticipantStatus.CONTRIBUTING */;
|
|
1350
1355
|
newContributionStep = "DOWNLOADING" /* ParticipantContributionStep.DOWNLOADING */;
|
|
1351
1356
|
// Remove from waiting queue of circuit X.
|
|
@@ -1363,7 +1368,7 @@ const coordinate = async (participant, circuit, isSingleParticipantCoordination,
|
|
|
1363
1368
|
contributionStartedAt: getCurrentServerTimestampInMillis(),
|
|
1364
1369
|
lastUpdated: getCurrentServerTimestampInMillis()
|
|
1365
1370
|
});
|
|
1366
|
-
printLog(`Participant ${newCurrentContributorId} is the new current contributor for circuit ${circuit.id}`, LogLevel.
|
|
1371
|
+
printLog(`Participant ${newCurrentContributorId} is the new current contributor for circuit ${circuit.id}`, LogLevel.INFO);
|
|
1367
1372
|
}
|
|
1368
1373
|
}
|
|
1369
1374
|
// Prepare tx - must be done for all Scenarios.
|
|
@@ -1440,8 +1445,8 @@ const waitForVMCommandExecution = (ssm, vmInstanceId, commandId) => new Promise(
|
|
|
1440
1445
|
try {
|
|
1441
1446
|
await stopEC2Instance(ec2, vmInstanceId);
|
|
1442
1447
|
}
|
|
1443
|
-
catch (
|
|
1444
|
-
printLog(`Error while stopping VM instance ${vmInstanceId} - Error ${
|
|
1448
|
+
catch (stopError) {
|
|
1449
|
+
printLog(`Error while stopping VM instance ${vmInstanceId} - Error ${stopError}`, LogLevel.WARN);
|
|
1445
1450
|
}
|
|
1446
1451
|
if (!error.toString().includes(commandId))
|
|
1447
1452
|
logAndThrowError(COMMON_ERRORS.CM_INVALID_COMMAND_EXECUTION);
|
|
@@ -1489,8 +1494,8 @@ const coordinateCeremonyParticipant = functionsV1
|
|
|
1489
1494
|
// Extract data.
|
|
1490
1495
|
const { contributionProgress: prevContributionProgress, status: prevStatus, contributionStep: prevContributionStep } = exParticipant.data();
|
|
1491
1496
|
const { contributionProgress: changedContributionProgress, status: changedStatus, contributionStep: changedContributionStep } = changedParticipant.data();
|
|
1492
|
-
printLog(`Coordinate participant ${exParticipant.id} for ceremony ${ceremonyId}`, LogLevel.
|
|
1493
|
-
printLog(`Participant status: ${prevStatus} => ${changedStatus} - Participant contribution step: ${prevContributionStep} => ${changedContributionStep}`, LogLevel.
|
|
1497
|
+
printLog(`Coordinate participant ${exParticipant.id} for ceremony ${ceremonyId}`, LogLevel.INFO);
|
|
1498
|
+
printLog(`Participant status: ${prevStatus} => ${changedStatus} - Participant contribution step: ${prevContributionStep} => ${changedContributionStep}`, LogLevel.INFO);
|
|
1494
1499
|
// Define pre-conditions.
|
|
1495
1500
|
const participantReadyToContribute = changedStatus === "READY" /* ParticipantStatus.READY */;
|
|
1496
1501
|
const participantReadyForFirstContribution = participantReadyToContribute && prevContributionProgress === 0;
|
|
@@ -1500,8 +1505,8 @@ const coordinateCeremonyParticipant = functionsV1
|
|
|
1500
1505
|
prevContributionProgress !== 0;
|
|
1501
1506
|
const participantCompletedEveryCircuitContribution = changedStatus === "DONE" /* ParticipantStatus.DONE */ && prevStatus !== "DONE" /* ParticipantStatus.DONE */;
|
|
1502
1507
|
const participantCompletedContribution = prevContributionProgress === changedContributionProgress &&
|
|
1503
|
-
prevStatus === "CONTRIBUTING" /* ParticipantStatus.CONTRIBUTING */
|
|
1504
|
-
|
|
1508
|
+
(prevStatus === "CONTRIBUTING" /* ParticipantStatus.CONTRIBUTING */ ||
|
|
1509
|
+
prevContributionStep === "VERIFYING" /* ParticipantContributionStep.VERIFYING */) &&
|
|
1505
1510
|
changedStatus === "CONTRIBUTED" /* ParticipantStatus.CONTRIBUTED */ &&
|
|
1506
1511
|
changedContributionStep === "COMPLETED" /* ParticipantContributionStep.COMPLETED */;
|
|
1507
1512
|
// Step (2).
|
|
@@ -1509,7 +1514,7 @@ const coordinateCeremonyParticipant = functionsV1
|
|
|
1509
1514
|
participantResumingContributionAfterTimeout ||
|
|
1510
1515
|
participantReadyForNextContribution) {
|
|
1511
1516
|
// Step (2.A).
|
|
1512
|
-
printLog(`Participant is ready for first contribution (${participantReadyForFirstContribution}) or for the next contribution (${participantReadyForNextContribution}) or is resuming after a timeout expiration (${participantResumingContributionAfterTimeout})`, LogLevel.
|
|
1517
|
+
printLog(`Participant is ready for first contribution (${participantReadyForFirstContribution}) or for the next contribution (${participantReadyForNextContribution}) or is resuming after a timeout expiration (${participantResumingContributionAfterTimeout})`, LogLevel.INFO);
|
|
1513
1518
|
// Get the circuit.
|
|
1514
1519
|
const circuit = await getCircuitDocumentByPosition(ceremonyId, changedContributionProgress);
|
|
1515
1520
|
// Coordinate.
|
|
@@ -1518,7 +1523,7 @@ const coordinateCeremonyParticipant = functionsV1
|
|
|
1518
1523
|
}
|
|
1519
1524
|
else if (participantCompletedContribution || participantCompletedEveryCircuitContribution) {
|
|
1520
1525
|
// Step (2.B).
|
|
1521
|
-
printLog(`Participant completed a contribution (${participantCompletedContribution}) or every contribution for each circuit (${participantCompletedEveryCircuitContribution})`, LogLevel.
|
|
1526
|
+
printLog(`Participant completed a contribution (${participantCompletedContribution}) or every contribution for each circuit (${participantCompletedEveryCircuitContribution})`, LogLevel.INFO);
|
|
1522
1527
|
// Get the circuit.
|
|
1523
1528
|
const circuit = await getCircuitDocumentByPosition(ceremonyId, prevContributionProgress);
|
|
1524
1529
|
// Coordinate.
|
|
@@ -1572,297 +1577,325 @@ const checkIfVMRunning = async (ec2, vmInstanceId, attempts = 5) => {
|
|
|
1572
1577
|
* 1.A.4.C.1) If true, update circuit waiting for queue and average timings accordingly to contribution verification results;
|
|
1573
1578
|
* 2) Send all updates atomically to the Firestore database.
|
|
1574
1579
|
*/
|
|
1575
|
-
const verifycontribution = functionsV2.https.onCall({ memory: "
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
!request.data.
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
!process.env.
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
//
|
|
1646
|
-
|
|
1647
|
-
verificationTaskTimer.
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
// Download from bucket.
|
|
1654
|
-
// nb. the transcript MUST be uploaded from the VM by verification commands.
|
|
1655
|
-
await downloadArtifactFromS3Bucket(bucketName, verificationTranscriptStoragePathAndFilename, verificationTranscriptTemporaryLocalPath);
|
|
1656
|
-
// Read the verification trascript and validate data by checking for core info ("ZKey Ok!").
|
|
1657
|
-
const content = fs.readFileSync(verificationTranscriptTemporaryLocalPath, "utf-8");
|
|
1658
|
-
if (content.includes("ZKey Ok!"))
|
|
1659
|
-
isContributionValid = true;
|
|
1660
|
-
// If the contribution is valid, then format and store the trascript.
|
|
1661
|
-
if (isContributionValid) {
|
|
1662
|
-
// eslint-disable-next-line no-control-regex
|
|
1663
|
-
const updated = content.replace(/\x1b[[0-9;]*m/g, "");
|
|
1664
|
-
fs.writeFileSync(verificationTranscriptTemporaryLocalPath, updated);
|
|
1580
|
+
const verifycontribution = functionsV2.https.onCall({ memory: "32GiB", timeoutSeconds: 3600, region: "europe-west1", cpu: 8 }, async (request) => {
|
|
1581
|
+
try {
|
|
1582
|
+
if (!request.auth || (!request.auth.token.participant && !request.auth.token.coordinator))
|
|
1583
|
+
logAndThrowError(SPECIFIC_ERRORS.SE_AUTH_NO_CURRENT_AUTH_USER);
|
|
1584
|
+
if (!request.data.ceremonyId ||
|
|
1585
|
+
!request.data.circuitId ||
|
|
1586
|
+
!request.data.contributorOrCoordinatorIdentifier ||
|
|
1587
|
+
!request.data.bucketName)
|
|
1588
|
+
logAndThrowError(COMMON_ERRORS.CM_MISSING_OR_WRONG_INPUT_DATA);
|
|
1589
|
+
if (!process.env.CUSTOM_CONTRIBUTION_VERIFICATION_SOFTWARE_NAME ||
|
|
1590
|
+
!process.env.CUSTOM_CONTRIBUTION_VERIFICATION_SOFTWARE_VERSION ||
|
|
1591
|
+
!process.env.CUSTOM_CONTRIBUTION_VERIFICATION_SOFTWARE_COMMIT_HASH)
|
|
1592
|
+
logAndThrowError(COMMON_ERRORS.CM_WRONG_CONFIGURATION);
|
|
1593
|
+
const BUCKET_NAME_REGEX = /^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$/;
|
|
1594
|
+
if (!BUCKET_NAME_REGEX.test(request.data.bucketName))
|
|
1595
|
+
logAndThrowError(SPECIFIC_ERRORS.WRONG_BUCKET_NAME);
|
|
1596
|
+
// Step (0).
|
|
1597
|
+
// Prepare and start timer.
|
|
1598
|
+
const verifyContributionTimer = new Timer({ label: commonTerms.cloudFunctionsNames.verifyContribution });
|
|
1599
|
+
verifyContributionTimer.start();
|
|
1600
|
+
// Get DB.
|
|
1601
|
+
const firestore = admin.firestore();
|
|
1602
|
+
// Prepare batch of txs.
|
|
1603
|
+
const batch = firestore.batch();
|
|
1604
|
+
// Extract data.
|
|
1605
|
+
const { ceremonyId, circuitId, contributorOrCoordinatorIdentifier, bucketName } = request.data;
|
|
1606
|
+
const userId = request.auth?.uid;
|
|
1607
|
+
// Look for the ceremony, circuit and participant document.
|
|
1608
|
+
const ceremonyDoc = await getDocumentById(commonTerms.collections.ceremonies.name, ceremonyId);
|
|
1609
|
+
const circuitDoc = await getDocumentById(getCircuitsCollectionPath(ceremonyId), circuitId);
|
|
1610
|
+
const participantDoc = await getDocumentById(getParticipantsCollectionPath(ceremonyId), userId);
|
|
1611
|
+
if (!ceremonyDoc.data() || !circuitDoc.data() || !participantDoc.data())
|
|
1612
|
+
logAndThrowError(COMMON_ERRORS.CM_INEXISTENT_DOCUMENT_DATA);
|
|
1613
|
+
// Extract documents data.
|
|
1614
|
+
const { state } = ceremonyDoc.data();
|
|
1615
|
+
const { status, contributions, verificationStartedAt, contributionStartedAt } = participantDoc.data();
|
|
1616
|
+
const { waitingQueue, prefix, avgTimings, verification, files } = circuitDoc.data();
|
|
1617
|
+
const { completedContributions, failedContributions } = waitingQueue;
|
|
1618
|
+
const { contributionComputation: avgContributionComputationTime, fullContribution: avgFullContributionTime, verifyCloudFunction: avgVerifyCloudFunctionTime } = avgTimings;
|
|
1619
|
+
const { cfOrVm, vm } = verification;
|
|
1620
|
+
// we might not have it if the circuit is not using VM.
|
|
1621
|
+
let vmInstanceId = "";
|
|
1622
|
+
if (vm)
|
|
1623
|
+
vmInstanceId = vm.vmInstanceId;
|
|
1624
|
+
// Define pre-conditions.
|
|
1625
|
+
const isFinalizing = state === "CLOSED" /* CeremonyState.CLOSED */ && request.auth && request.auth.token.coordinator; // true only when the coordinator verifies the final contributions.
|
|
1626
|
+
const isContributing = status === "CONTRIBUTING" /* ParticipantStatus.CONTRIBUTING */;
|
|
1627
|
+
const isUsingVM = cfOrVm === "VM" /* CircuitContributionVerificationMechanism.VM */ && !!vmInstanceId;
|
|
1628
|
+
// Prepare state.
|
|
1629
|
+
let isContributionValid = false;
|
|
1630
|
+
let verifyCloudFunctionExecutionTime = 0; // time spent while executing the verify contribution cloud function.
|
|
1631
|
+
let verifyCloudFunctionTime = 0; // time spent while executing the core business logic of this cloud function.
|
|
1632
|
+
let fullContributionTime = 0; // time spent while doing non-verification contributions tasks (download, compute, upload).
|
|
1633
|
+
let contributionComputationTime = 0; // time spent while computing the contribution.
|
|
1634
|
+
let lastZkeyBlake2bHash = ""; // the Blake2B hash of the last zKey.
|
|
1635
|
+
let verificationTranscriptTemporaryLocalPath = ""; // the local temporary path for the verification transcript.
|
|
1636
|
+
let transcriptBlake2bHash = ""; // the Blake2B hash of the verification transcript.
|
|
1637
|
+
let commandId = ""; // the unique identifier of the VM command.
|
|
1638
|
+
// Derive necessary data.
|
|
1639
|
+
const lastZkeyIndex = formatZkeyIndex(completedContributions + 1);
|
|
1640
|
+
const verificationTranscriptCompleteFilename = `${prefix}_${isFinalizing
|
|
1641
|
+
? `${contributorOrCoordinatorIdentifier}_${finalContributionIndex}_verification_transcript.log`
|
|
1642
|
+
: `${lastZkeyIndex}_${contributorOrCoordinatorIdentifier}_verification_transcript.log`}`;
|
|
1643
|
+
const lastZkeyFilename = `${prefix}_${isFinalizing ? finalContributionIndex : lastZkeyIndex}.zkey`;
|
|
1644
|
+
// Prepare state for VM verification (if needed).
|
|
1645
|
+
const ec2 = await createEC2Client();
|
|
1646
|
+
const ssm = await createSSMClient();
|
|
1647
|
+
// Step (1.A.1).
|
|
1648
|
+
// Get storage paths.
|
|
1649
|
+
const verificationTranscriptStoragePathAndFilename = getTranscriptStorageFilePath(prefix, verificationTranscriptCompleteFilename);
|
|
1650
|
+
// the zKey storage path is required to be sent to the VM api
|
|
1651
|
+
const lastZkeyStoragePath = getZkeyStorageFilePath(prefix, `${prefix}_${isFinalizing ? finalContributionIndex : lastZkeyIndex}.zkey`);
|
|
1652
|
+
const verificationTaskTimer = new Timer({ label: `${ceremonyId}-${circuitId}-${participantDoc.id}` });
|
|
1653
|
+
const dumpLog = async (path) => {
|
|
1654
|
+
printLog(`transcript >>>>>>`, LogLevel.DEBUG);
|
|
1655
|
+
try {
|
|
1656
|
+
const data = await fs.promises.readFile(path, "utf8");
|
|
1657
|
+
printLog(data, LogLevel.DEBUG);
|
|
1665
1658
|
}
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
.
|
|
1672
|
-
.
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
// Sleep ~3 seconds to wait for verification transcription.
|
|
1676
|
-
await sleep(3000);
|
|
1677
|
-
// Step (1.A.4.A.1).
|
|
1659
|
+
catch (readError) {
|
|
1660
|
+
printLog(readError, LogLevel.ERROR);
|
|
1661
|
+
}
|
|
1662
|
+
};
|
|
1663
|
+
const completeVerification = async () => {
|
|
1664
|
+
// Stop verification task timer.
|
|
1665
|
+
printLog("Completing verification", LogLevel.DEBUG);
|
|
1666
|
+
verificationTaskTimer.stop();
|
|
1667
|
+
verifyCloudFunctionExecutionTime = verificationTaskTimer.ms();
|
|
1678
1668
|
if (isUsingVM) {
|
|
1679
|
-
//
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1669
|
+
// Create temporary path.
|
|
1670
|
+
verificationTranscriptTemporaryLocalPath = createTemporaryLocalPath(`${circuitId}_${participantDoc.id}.log`);
|
|
1671
|
+
await sleep(1000); // wait 1s for file creation.
|
|
1672
|
+
// Download from bucket.
|
|
1673
|
+
// nb. the transcript MUST be uploaded from the VM by verification commands.
|
|
1674
|
+
await downloadArtifactFromS3Bucket(bucketName, verificationTranscriptStoragePathAndFilename, verificationTranscriptTemporaryLocalPath);
|
|
1675
|
+
// Read the verification trascript and validate data by checking for core info ("ZKey Ok!").
|
|
1676
|
+
const content = fs.readFileSync(verificationTranscriptTemporaryLocalPath, "utf-8");
|
|
1677
|
+
if (content.includes("ZKey Ok!"))
|
|
1678
|
+
isContributionValid = true;
|
|
1679
|
+
// If the contribution is valid, then format and store the trascript.
|
|
1680
|
+
if (isContributionValid) {
|
|
1681
|
+
// eslint-disable-next-line no-control-regex
|
|
1682
|
+
const updated = content.replace(/\x1b[[0-9;]*m/g, "");
|
|
1683
|
+
fs.writeFileSync(verificationTranscriptTemporaryLocalPath, updated);
|
|
1684
|
+
}
|
|
1685
|
+
}
|
|
1686
|
+
printLog(`The contribution has been verified - Result ${isContributionValid}`, LogLevel.DEBUG);
|
|
1687
|
+
// Create a new contribution document.
|
|
1688
|
+
const contributionDoc = await firestore
|
|
1689
|
+
.collection(getContributionsCollectionPath(ceremonyId, circuitId))
|
|
1690
|
+
.doc()
|
|
1691
|
+
.get();
|
|
1692
|
+
// Step (1.A.4).
|
|
1693
|
+
if (isContributionValid) {
|
|
1694
|
+
// Sleep ~3 seconds to wait for verification transcription.
|
|
1695
|
+
await sleep(3000);
|
|
1696
|
+
// Step (1.A.4.A.1).
|
|
1697
|
+
if (isUsingVM) {
|
|
1698
|
+
// Retrieve the contribution hash from the command output.
|
|
1699
|
+
lastZkeyBlake2bHash = await retrieveCommandOutput(ssm, vmInstanceId, commandId);
|
|
1700
|
+
const hashRegex = /[a-fA-F0-9]{64}/;
|
|
1701
|
+
const match = lastZkeyBlake2bHash.match(hashRegex);
|
|
1702
|
+
lastZkeyBlake2bHash = match.at(0);
|
|
1703
|
+
// re upload the formatted verification transcript
|
|
1704
|
+
await uploadFileToBucket(bucketName, verificationTranscriptStoragePathAndFilename, verificationTranscriptTemporaryLocalPath, true);
|
|
1705
|
+
}
|
|
1706
|
+
else {
|
|
1707
|
+
// Upload verification transcript.
|
|
1708
|
+
/// nb. do not use multi-part upload here due to small file size.
|
|
1709
|
+
await uploadFileToBucket(bucketName, verificationTranscriptStoragePathAndFilename, verificationTranscriptTemporaryLocalPath, true);
|
|
1710
|
+
}
|
|
1711
|
+
// Compute verification transcript hash.
|
|
1712
|
+
transcriptBlake2bHash = await blake512FromPath(verificationTranscriptTemporaryLocalPath);
|
|
1713
|
+
// Free resources by unlinking transcript temporary file.
|
|
1714
|
+
fs.unlinkSync(verificationTranscriptTemporaryLocalPath);
|
|
1715
|
+
// Filter participant contributions to find the data related to the one verified.
|
|
1716
|
+
const participantContributions = contributions.filter((contribution) => !!contribution.hash && !!contribution.computationTime && !contribution.doc);
|
|
1717
|
+
/// @dev (there must be only one contribution with an empty 'doc' field).
|
|
1718
|
+
if (participantContributions.length !== 1)
|
|
1719
|
+
logAndThrowError(SPECIFIC_ERRORS.SE_VERIFICATION_NO_PARTICIPANT_CONTRIBUTION_DATA);
|
|
1720
|
+
// Get contribution computation time.
|
|
1721
|
+
contributionComputationTime = contributions.at(0).computationTime;
|
|
1722
|
+
// Step (1.A.4.A.2).
|
|
1723
|
+
batch.create(contributionDoc.ref, {
|
|
1724
|
+
participantId: participantDoc.id,
|
|
1725
|
+
contributionComputationTime,
|
|
1726
|
+
verificationComputationTime: verifyCloudFunctionExecutionTime,
|
|
1727
|
+
zkeyIndex: isFinalizing ? finalContributionIndex : lastZkeyIndex,
|
|
1728
|
+
files: {
|
|
1729
|
+
transcriptFilename: verificationTranscriptCompleteFilename,
|
|
1730
|
+
lastZkeyFilename,
|
|
1731
|
+
transcriptStoragePath: verificationTranscriptStoragePathAndFilename,
|
|
1732
|
+
lastZkeyStoragePath,
|
|
1733
|
+
transcriptBlake2bHash,
|
|
1734
|
+
lastZkeyBlake2bHash
|
|
1735
|
+
},
|
|
1736
|
+
verificationSoftware: {
|
|
1737
|
+
name: String(process.env.CUSTOM_CONTRIBUTION_VERIFICATION_SOFTWARE_NAME),
|
|
1738
|
+
version: String(process.env.CUSTOM_CONTRIBUTION_VERIFICATION_SOFTWARE_VERSION),
|
|
1739
|
+
commitHash: String(process.env.CUSTOM_CONTRIBUTION_VERIFICATION_SOFTWARE_COMMIT_HASH)
|
|
1740
|
+
},
|
|
1741
|
+
valid: isContributionValid,
|
|
1742
|
+
lastUpdated: getCurrentServerTimestampInMillis()
|
|
1743
|
+
});
|
|
1744
|
+
verifyContributionTimer.stop();
|
|
1745
|
+
verifyCloudFunctionTime = verifyContributionTimer.ms();
|
|
1686
1746
|
}
|
|
1687
1747
|
else {
|
|
1688
|
-
//
|
|
1689
|
-
|
|
1690
|
-
await
|
|
1748
|
+
// Step (1.A.4.B).
|
|
1749
|
+
// Free-up storage by deleting invalid contribution.
|
|
1750
|
+
await deleteObject(bucketName, lastZkeyStoragePath);
|
|
1751
|
+
// Step (1.A.4.B.1).
|
|
1752
|
+
batch.create(contributionDoc.ref, {
|
|
1753
|
+
participantId: participantDoc.id,
|
|
1754
|
+
verificationComputationTime: verifyCloudFunctionExecutionTime,
|
|
1755
|
+
zkeyIndex: isFinalizing ? finalContributionIndex : lastZkeyIndex,
|
|
1756
|
+
verificationSoftware: {
|
|
1757
|
+
name: String(process.env.CUSTOM_CONTRIBUTION_VERIFICATION_SOFTWARE_NAME),
|
|
1758
|
+
version: String(process.env.CUSTOM_CONTRIBUTION_VERIFICATION_SOFTWARE_VERSION),
|
|
1759
|
+
commitHash: String(process.env.CUSTOM_CONTRIBUTION_VERIFICATION_SOFTWARE_COMMIT_HASH)
|
|
1760
|
+
},
|
|
1761
|
+
valid: isContributionValid,
|
|
1762
|
+
lastUpdated: getCurrentServerTimestampInMillis()
|
|
1763
|
+
});
|
|
1691
1764
|
}
|
|
1692
|
-
//
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
//
|
|
1765
|
+
// Stop VM instance
|
|
1766
|
+
if (isUsingVM) {
|
|
1767
|
+
// using try and catch as the VM stopping function can throw
|
|
1768
|
+
// however we want to continue without stopping as the
|
|
1769
|
+
// verification was valid, and inform the coordinator
|
|
1770
|
+
try {
|
|
1771
|
+
await stopEC2Instance(ec2, vmInstanceId);
|
|
1772
|
+
}
|
|
1773
|
+
catch (error) {
|
|
1774
|
+
printLog(`Error while stopping VM instance ${vmInstanceId} - Error ${error}`, LogLevel.WARN);
|
|
1775
|
+
}
|
|
1776
|
+
}
|
|
1777
|
+
// Step (1.A.4.C)
|
|
1778
|
+
if (!isFinalizing) {
|
|
1779
|
+
// Step (1.A.4.C.1)
|
|
1780
|
+
// Compute new average contribution/verification time.
|
|
1781
|
+
fullContributionTime = Number(verificationStartedAt) - Number(contributionStartedAt);
|
|
1782
|
+
const newAvgContributionComputationTime = avgContributionComputationTime > 0
|
|
1783
|
+
? (avgContributionComputationTime + contributionComputationTime) / 2
|
|
1784
|
+
: contributionComputationTime;
|
|
1785
|
+
const newAvgFullContributionTime = avgFullContributionTime > 0
|
|
1786
|
+
? (avgFullContributionTime + fullContributionTime) / 2
|
|
1787
|
+
: fullContributionTime;
|
|
1788
|
+
const newAvgVerifyCloudFunctionTime = avgVerifyCloudFunctionTime > 0
|
|
1789
|
+
? (avgVerifyCloudFunctionTime + verifyCloudFunctionTime) / 2
|
|
1790
|
+
: verifyCloudFunctionTime;
|
|
1791
|
+
// Prepare tx to update circuit average contribution/verification time.
|
|
1792
|
+
const updatedCircuitDoc = await getDocumentById(getCircuitsCollectionPath(ceremonyId), circuitId);
|
|
1793
|
+
const { waitingQueue: updatedWaitingQueue } = updatedCircuitDoc.data();
|
|
1794
|
+
/// @dev this must happen only for valid contributions.
|
|
1795
|
+
batch.update(circuitDoc.ref, {
|
|
1796
|
+
avgTimings: {
|
|
1797
|
+
contributionComputation: isContributionValid
|
|
1798
|
+
? newAvgContributionComputationTime
|
|
1799
|
+
: avgContributionComputationTime,
|
|
1800
|
+
fullContribution: isContributionValid
|
|
1801
|
+
? newAvgFullContributionTime
|
|
1802
|
+
: avgFullContributionTime,
|
|
1803
|
+
verifyCloudFunction: isContributionValid
|
|
1804
|
+
? newAvgVerifyCloudFunctionTime
|
|
1805
|
+
: avgVerifyCloudFunctionTime
|
|
1806
|
+
},
|
|
1807
|
+
waitingQueue: {
|
|
1808
|
+
...updatedWaitingQueue,
|
|
1809
|
+
completedContributions: isContributionValid
|
|
1810
|
+
? completedContributions + 1
|
|
1811
|
+
: completedContributions,
|
|
1812
|
+
failedContributions: isContributionValid ? failedContributions : failedContributions + 1
|
|
1813
|
+
},
|
|
1814
|
+
lastUpdated: getCurrentServerTimestampInMillis()
|
|
1815
|
+
});
|
|
1816
|
+
}
|
|
1817
|
+
// Step (2).
|
|
1818
|
+
await batch.commit();
|
|
1819
|
+
printLog(`The contribution #${isFinalizing ? finalContributionIndex : lastZkeyIndex} of circuit ${circuitId} (ceremony ${ceremonyId}) has been verified as ${isContributionValid ? "valid" : "invalid"} for the participant ${participantDoc.id}`, LogLevel.INFO);
|
|
1820
|
+
};
|
|
1821
|
+
// Step (1).
|
|
1822
|
+
if (isContributing || isFinalizing) {
|
|
1823
|
+
// Prepare timer.
|
|
1824
|
+
verificationTaskTimer.start();
|
|
1825
|
+
// Step (1.A.3.0).
|
|
1826
|
+
if (isUsingVM) {
|
|
1827
|
+
printLog(`Starting the VM mechanism`, LogLevel.DEBUG);
|
|
1828
|
+
// Prepare for VM execution.
|
|
1829
|
+
let isVMRunning = false; // true when the VM is up, otherwise false.
|
|
1830
|
+
// Step (1.A.3.1).
|
|
1831
|
+
await startEC2Instance(ec2, vmInstanceId);
|
|
1832
|
+
await sleep(60000); // nb. wait for VM startup (1 mins + retry).
|
|
1833
|
+
// Check if the startup is running.
|
|
1834
|
+
isVMRunning = await checkIfVMRunning(ec2, vmInstanceId);
|
|
1835
|
+
printLog(`VM running: ${isVMRunning}`, LogLevel.DEBUG);
|
|
1836
|
+
// Step (1.A.3.2).
|
|
1837
|
+
// Prepare.
|
|
1838
|
+
const verificationCommand = vmContributionVerificationCommand(bucketName, lastZkeyStoragePath, verificationTranscriptStoragePathAndFilename);
|
|
1839
|
+
// Run.
|
|
1840
|
+
commandId = await runCommandUsingSSM(ssm, vmInstanceId, verificationCommand);
|
|
1841
|
+
printLog(`Starting the execution of command ${commandId}`, LogLevel.DEBUG);
|
|
1842
|
+
// Step (1.A.3.3).
|
|
1843
|
+
return await waitForVMCommandExecution(ssm, vmInstanceId, commandId)
|
|
1844
|
+
.then(async () => {
|
|
1845
|
+
// Command execution successfully completed.
|
|
1846
|
+
printLog(`Command ${commandId} execution has been successfully completed`, LogLevel.DEBUG);
|
|
1847
|
+
await completeVerification();
|
|
1848
|
+
})
|
|
1849
|
+
.catch((error) => {
|
|
1850
|
+
// Command execution aborted.
|
|
1851
|
+
printLog(`Command ${commandId} execution has been aborted - Error ${error}`, LogLevel.WARN);
|
|
1852
|
+
logAndThrowError(COMMON_ERRORS.CM_INVALID_COMMAND_EXECUTION);
|
|
1853
|
+
});
|
|
1854
|
+
}
|
|
1855
|
+
// CF approach.
|
|
1856
|
+
printLog(`CF mechanism`, LogLevel.DEBUG);
|
|
1857
|
+
const potStoragePath = getPotStorageFilePath(files.potFilename);
|
|
1858
|
+
const firstZkeyStoragePath = getZkeyStorageFilePath(prefix, `${prefix}_${genesisZkeyIndex}.zkey`);
|
|
1859
|
+
printLog(`pot file: ${potStoragePath}`, LogLevel.DEBUG);
|
|
1860
|
+
printLog(`zkey file: ${firstZkeyStoragePath}`, LogLevel.DEBUG);
|
|
1861
|
+
// Prepare temporary file paths.
|
|
1862
|
+
// (nb. these are needed to download the necessary artifacts for verification from AWS S3).
|
|
1863
|
+
verificationTranscriptTemporaryLocalPath = createTemporaryLocalPath(verificationTranscriptCompleteFilename);
|
|
1864
|
+
const potTempFilePath = createTemporaryLocalPath(`${circuitId}_${participantDoc.id}.pot`);
|
|
1865
|
+
const firstZkeyTempFilePath = createTemporaryLocalPath(`${circuitId}_${participantDoc.id}_genesis.zkey`);
|
|
1866
|
+
const lastZkeyTempFilePath = createTemporaryLocalPath(`${circuitId}_${participantDoc.id}_last.zkey`);
|
|
1867
|
+
printLog(`pot file: ${potTempFilePath}`, LogLevel.DEBUG);
|
|
1868
|
+
printLog(`firstZkey file: ${firstZkeyTempFilePath}`, LogLevel.DEBUG);
|
|
1869
|
+
printLog(`last zkey file: ${lastZkeyTempFilePath}`, LogLevel.DEBUG);
|
|
1870
|
+
// Create and populate transcript.
|
|
1871
|
+
const transcriptLogger = createCustomLoggerForFile(verificationTranscriptTemporaryLocalPath);
|
|
1872
|
+
transcriptLogger.info(`${isFinalizing ? `Final verification` : `Verification`} transcript for ${prefix} circuit Phase 2 contribution.\n${isFinalizing ? `Coordinator ` : `Contributor # ${Number(lastZkeyIndex)}`} (${contributorOrCoordinatorIdentifier})\n`);
|
|
1873
|
+
// Step (1.A.2).
|
|
1874
|
+
await downloadArtifactFromS3Bucket(bucketName, potStoragePath, potTempFilePath);
|
|
1875
|
+
await downloadArtifactFromS3Bucket(bucketName, firstZkeyStoragePath, firstZkeyTempFilePath);
|
|
1876
|
+
await downloadArtifactFromS3Bucket(bucketName, lastZkeyStoragePath, lastZkeyTempFilePath);
|
|
1877
|
+
// Step (1.A.4).
|
|
1878
|
+
isContributionValid = await zKey.verifyFromInit(firstZkeyTempFilePath, potTempFilePath, lastZkeyTempFilePath, transcriptLogger);
|
|
1879
|
+
await dumpLog(verificationTranscriptTemporaryLocalPath);
|
|
1880
|
+
// Compute contribution hash.
|
|
1881
|
+
lastZkeyBlake2bHash = await blake512FromPath(lastZkeyTempFilePath);
|
|
1882
|
+
// Free resources by unlinking temporary folders.
|
|
1883
|
+
// Do not free-up verification transcript path here.
|
|
1751
1884
|
try {
|
|
1752
|
-
|
|
1885
|
+
fs.unlinkSync(potTempFilePath);
|
|
1886
|
+
fs.unlinkSync(firstZkeyTempFilePath);
|
|
1887
|
+
fs.unlinkSync(lastZkeyTempFilePath);
|
|
1753
1888
|
}
|
|
1754
1889
|
catch (error) {
|
|
1755
|
-
printLog(`Error while
|
|
1890
|
+
printLog(`Error while unlinking temporary files - Error ${error}`, LogLevel.WARN);
|
|
1756
1891
|
}
|
|
1892
|
+
await completeVerification();
|
|
1757
1893
|
}
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
const newAvgContributionComputationTime = avgContributionComputationTime > 0
|
|
1764
|
-
? (avgContributionComputationTime + contributionComputationTime) / 2
|
|
1765
|
-
: contributionComputationTime;
|
|
1766
|
-
const newAvgFullContributionTime = avgFullContributionTime > 0
|
|
1767
|
-
? (avgFullContributionTime + fullContributionTime) / 2
|
|
1768
|
-
: fullContributionTime;
|
|
1769
|
-
const newAvgVerifyCloudFunctionTime = avgVerifyCloudFunctionTime > 0
|
|
1770
|
-
? (avgVerifyCloudFunctionTime + verifyCloudFunctionTime) / 2
|
|
1771
|
-
: verifyCloudFunctionTime;
|
|
1772
|
-
// Prepare tx to update circuit average contribution/verification time.
|
|
1773
|
-
const updatedCircuitDoc = await getDocumentById(getCircuitsCollectionPath(ceremonyId), circuitId);
|
|
1774
|
-
const { waitingQueue: updatedWaitingQueue } = updatedCircuitDoc.data();
|
|
1775
|
-
/// @dev this must happen only for valid contributions.
|
|
1776
|
-
batch.update(circuitDoc.ref, {
|
|
1777
|
-
avgTimings: {
|
|
1778
|
-
contributionComputation: isContributionValid
|
|
1779
|
-
? newAvgContributionComputationTime
|
|
1780
|
-
: avgContributionComputationTime,
|
|
1781
|
-
fullContribution: isContributionValid ? newAvgFullContributionTime : avgFullContributionTime,
|
|
1782
|
-
verifyCloudFunction: isContributionValid
|
|
1783
|
-
? newAvgVerifyCloudFunctionTime
|
|
1784
|
-
: avgVerifyCloudFunctionTime
|
|
1785
|
-
},
|
|
1786
|
-
waitingQueue: {
|
|
1787
|
-
...updatedWaitingQueue,
|
|
1788
|
-
completedContributions: isContributionValid
|
|
1789
|
-
? completedContributions + 1
|
|
1790
|
-
: completedContributions,
|
|
1791
|
-
failedContributions: isContributionValid ? failedContributions : failedContributions + 1
|
|
1792
|
-
},
|
|
1793
|
-
lastUpdated: getCurrentServerTimestampInMillis()
|
|
1794
|
-
});
|
|
1795
|
-
}
|
|
1796
|
-
// Step (2).
|
|
1797
|
-
await batch.commit();
|
|
1798
|
-
printLog(`The contribution #${isFinalizing ? finalContributionIndex : lastZkeyIndex} of circuit ${circuitId} (ceremony ${ceremonyId}) has been verified as ${isContributionValid ? "valid" : "invalid"} for the participant ${participantDoc.id}`, LogLevel.DEBUG);
|
|
1799
|
-
};
|
|
1800
|
-
// Step (1).
|
|
1801
|
-
if (isContributing || isFinalizing) {
|
|
1802
|
-
// Prepare timer.
|
|
1803
|
-
verificationTaskTimer.start();
|
|
1804
|
-
// Step (1.A.3.0).
|
|
1805
|
-
if (isUsingVM) {
|
|
1806
|
-
printLog(`Starting the VM mechanism`, LogLevel.DEBUG);
|
|
1807
|
-
// Prepare for VM execution.
|
|
1808
|
-
let isVMRunning = false; // true when the VM is up, otherwise false.
|
|
1809
|
-
// Step (1.A.3.1).
|
|
1810
|
-
await startEC2Instance(ec2, vmInstanceId);
|
|
1811
|
-
await sleep(60000); // nb. wait for VM startup (1 mins + retry).
|
|
1812
|
-
// Check if the startup is running.
|
|
1813
|
-
isVMRunning = await checkIfVMRunning(ec2, vmInstanceId);
|
|
1814
|
-
printLog(`VM running: ${isVMRunning}`, LogLevel.DEBUG);
|
|
1815
|
-
// Step (1.A.3.2).
|
|
1816
|
-
// Prepare.
|
|
1817
|
-
const verificationCommand = vmContributionVerificationCommand(bucketName, lastZkeyStoragePath, verificationTranscriptStoragePathAndFilename);
|
|
1818
|
-
// Run.
|
|
1819
|
-
commandId = await runCommandUsingSSM(ssm, vmInstanceId, verificationCommand);
|
|
1820
|
-
printLog(`Starting the execution of command ${commandId}`, LogLevel.DEBUG);
|
|
1821
|
-
// Step (1.A.3.3).
|
|
1822
|
-
return waitForVMCommandExecution(ssm, vmInstanceId, commandId)
|
|
1823
|
-
.then(async () => {
|
|
1824
|
-
// Command execution successfully completed.
|
|
1825
|
-
printLog(`Command ${commandId} execution has been successfully completed`, LogLevel.DEBUG);
|
|
1826
|
-
await completeVerification();
|
|
1827
|
-
})
|
|
1828
|
-
.catch((error) => {
|
|
1829
|
-
// Command execution aborted.
|
|
1830
|
-
printLog(`Command ${commandId} execution has been aborted - Error ${error}`, LogLevel.DEBUG);
|
|
1831
|
-
logAndThrowError(COMMON_ERRORS.CM_INVALID_COMMAND_EXECUTION);
|
|
1832
|
-
});
|
|
1833
|
-
}
|
|
1834
|
-
// CF approach.
|
|
1835
|
-
printLog(`CF mechanism`, LogLevel.DEBUG);
|
|
1836
|
-
const potStoragePath = getPotStorageFilePath(files.potFilename);
|
|
1837
|
-
const firstZkeyStoragePath = getZkeyStorageFilePath(prefix, `${prefix}_${genesisZkeyIndex}.zkey`);
|
|
1838
|
-
// Prepare temporary file paths.
|
|
1839
|
-
// (nb. these are needed to download the necessary artifacts for verification from AWS S3).
|
|
1840
|
-
verificationTranscriptTemporaryLocalPath = createTemporaryLocalPath(verificationTranscriptCompleteFilename);
|
|
1841
|
-
const potTempFilePath = createTemporaryLocalPath(`${circuitId}_${participantDoc.id}.pot`);
|
|
1842
|
-
const firstZkeyTempFilePath = createTemporaryLocalPath(`${circuitId}_${participantDoc.id}_genesis.zkey`);
|
|
1843
|
-
const lastZkeyTempFilePath = createTemporaryLocalPath(`${circuitId}_${participantDoc.id}_last.zkey`);
|
|
1844
|
-
// Create and populate transcript.
|
|
1845
|
-
const transcriptLogger = createCustomLoggerForFile(verificationTranscriptTemporaryLocalPath);
|
|
1846
|
-
transcriptLogger.info(`${isFinalizing ? `Final verification` : `Verification`} transcript for ${prefix} circuit Phase 2 contribution.\n${isFinalizing ? `Coordinator ` : `Contributor # ${Number(lastZkeyIndex)}`} (${contributorOrCoordinatorIdentifier})\n`);
|
|
1847
|
-
// Step (1.A.2).
|
|
1848
|
-
await downloadArtifactFromS3Bucket(bucketName, potStoragePath, potTempFilePath);
|
|
1849
|
-
await downloadArtifactFromS3Bucket(bucketName, firstZkeyStoragePath, firstZkeyTempFilePath);
|
|
1850
|
-
await downloadArtifactFromS3Bucket(bucketName, lastZkeyStoragePath, lastZkeyTempFilePath);
|
|
1851
|
-
// Step (1.A.4).
|
|
1852
|
-
isContributionValid = await zKey.verifyFromInit(firstZkeyTempFilePath, potTempFilePath, lastZkeyTempFilePath, transcriptLogger);
|
|
1853
|
-
// Compute contribution hash.
|
|
1854
|
-
lastZkeyBlake2bHash = await blake512FromPath(lastZkeyTempFilePath);
|
|
1855
|
-
// Free resources by unlinking temporary folders.
|
|
1856
|
-
// Do not free-up verification transcript path here.
|
|
1857
|
-
try {
|
|
1858
|
-
fs.unlinkSync(potTempFilePath);
|
|
1859
|
-
fs.unlinkSync(firstZkeyTempFilePath);
|
|
1860
|
-
fs.unlinkSync(lastZkeyTempFilePath);
|
|
1861
|
-
}
|
|
1862
|
-
catch (error) {
|
|
1863
|
-
printLog(`Error while unlinking temporary files - Error ${error}`, LogLevel.WARN);
|
|
1864
|
-
}
|
|
1865
|
-
await completeVerification();
|
|
1894
|
+
return null;
|
|
1895
|
+
}
|
|
1896
|
+
catch (error) {
|
|
1897
|
+
logAndThrowError(makeError("unknown", error));
|
|
1898
|
+
return null;
|
|
1866
1899
|
}
|
|
1867
1900
|
});
|
|
1868
1901
|
/**
|
|
@@ -1924,7 +1957,7 @@ const refreshParticipantAfterContributionVerification = functionsV1
|
|
|
1924
1957
|
lastUpdated: getCurrentServerTimestampInMillis()
|
|
1925
1958
|
});
|
|
1926
1959
|
await batch.commit();
|
|
1927
|
-
printLog(`Participant ${participantId} refreshed after contribution ${createdContribution.id} - The participant was finalizing the ceremony ${isFinalizing}`, LogLevel.
|
|
1960
|
+
printLog(`Participant ${participantId} refreshed after contribution ${createdContribution.id} - The participant was finalizing the ceremony? ${isFinalizing}`, LogLevel.INFO);
|
|
1928
1961
|
});
|
|
1929
1962
|
/**
|
|
1930
1963
|
* Finalize the ceremony circuit.
|
|
@@ -2089,6 +2122,7 @@ const createBucket = functions
|
|
|
2089
2122
|
// Connect to S3 client.
|
|
2090
2123
|
const S3 = await getS3Client();
|
|
2091
2124
|
try {
|
|
2125
|
+
printLog(`Creating AWS S3 bucket ${data.bucketName} ...`, LogLevel.LOG);
|
|
2092
2126
|
// Try to get information about the bucket.
|
|
2093
2127
|
await S3.send(new HeadBucketCommand({ Bucket: data.bucketName }));
|
|
2094
2128
|
// If the command succeeded, the bucket exists, throw an error.
|
|
@@ -2419,110 +2453,110 @@ const completeMultiPartUpload = functions
|
|
|
2419
2453
|
}
|
|
2420
2454
|
});
|
|
2421
2455
|
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
"
|
|
2438
|
-
"
|
|
2439
|
-
],
|
|
2440
|
-
["1", "0"]
|
|
2441
|
-
],
|
|
2442
|
-
vk_gamma_2: [
|
|
2443
|
-
[
|
|
2444
|
-
"10857046999023057135944570762232829481370756359578518086990519993285655852781",
|
|
2445
|
-
"11559732032986387107991004021392285783925812861821192530917403151452391805634"
|
|
2446
|
-
],
|
|
2447
|
-
[
|
|
2448
|
-
"8495653923123431417604973247489272438418190587263600148770280649306958101930",
|
|
2449
|
-
"4082367875863433681332203403145435568316851327593401208105741076214120093531"
|
|
2456
|
+
dotenv.config();
|
|
2457
|
+
const { BANDADA_API_URL, BANDADA_GROUP_ID } = process.env;
|
|
2458
|
+
const bandadaApi = new ApiSdk(BANDADA_API_URL);
|
|
2459
|
+
const bandadaValidateProof = functions
|
|
2460
|
+
.region("europe-west1")
|
|
2461
|
+
.runWith({
|
|
2462
|
+
memory: "1GB"
|
|
2463
|
+
})
|
|
2464
|
+
.https.onCall(async (data) => {
|
|
2465
|
+
const VKEY_DATA = {
|
|
2466
|
+
protocol: "groth16",
|
|
2467
|
+
curve: "bn128",
|
|
2468
|
+
nPublic: 3,
|
|
2469
|
+
vk_alpha_1: [
|
|
2470
|
+
"20491192805390485299153009773594534940189261866228447918068658471970481763042",
|
|
2471
|
+
"9383485363053290200918347156157836566562967994039712273449902621266178545958",
|
|
2472
|
+
"1"
|
|
2450
2473
|
],
|
|
2451
|
-
[
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2474
|
+
vk_beta_2: [
|
|
2475
|
+
[
|
|
2476
|
+
"6375614351688725206403948262868962793625744043794305715222011528459656738731",
|
|
2477
|
+
"4252822878758300859123897981450591353533073413197771768651442665752259397132"
|
|
2478
|
+
],
|
|
2479
|
+
[
|
|
2480
|
+
"10505242626370262277552901082094356697409835680220590971873171140371331206856",
|
|
2481
|
+
"21847035105528745403288232691147584728191162732299865338377159692350059136679"
|
|
2482
|
+
],
|
|
2483
|
+
["1", "0"]
|
|
2457
2484
|
],
|
|
2458
|
-
[
|
|
2459
|
-
|
|
2460
|
-
|
|
2485
|
+
vk_gamma_2: [
|
|
2486
|
+
[
|
|
2487
|
+
"10857046999023057135944570762232829481370756359578518086990519993285655852781",
|
|
2488
|
+
"11559732032986387107991004021392285783925812861821192530917403151452391805634"
|
|
2489
|
+
],
|
|
2490
|
+
[
|
|
2491
|
+
"8495653923123431417604973247489272438418190587263600148770280649306958101930",
|
|
2492
|
+
"4082367875863433681332203403145435568316851327593401208105741076214120093531"
|
|
2493
|
+
],
|
|
2494
|
+
["1", "0"]
|
|
2461
2495
|
],
|
|
2462
|
-
[
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2496
|
+
vk_delta_2: [
|
|
2497
|
+
[
|
|
2498
|
+
"3697618915467790705869942236922063775466274665053173890632463796679068973252",
|
|
2499
|
+
"14948341351907992175709156460547989243732741534604949238422596319735704165658"
|
|
2500
|
+
],
|
|
2466
2501
|
[
|
|
2467
|
-
"
|
|
2468
|
-
"
|
|
2502
|
+
"3028459181652799888716942141752307629938889957960373621898607910203491239368",
|
|
2503
|
+
"11380736494786911280692284374675752681598754560757720296073023058533044108340"
|
|
2469
2504
|
],
|
|
2505
|
+
["1", "0"]
|
|
2506
|
+
],
|
|
2507
|
+
vk_alphabeta_12: [
|
|
2470
2508
|
[
|
|
2471
|
-
|
|
2472
|
-
|
|
2509
|
+
[
|
|
2510
|
+
"2029413683389138792403550203267699914886160938906632433982220835551125967885",
|
|
2511
|
+
"21072700047562757817161031222997517981543347628379360635925549008442030252106"
|
|
2512
|
+
],
|
|
2513
|
+
[
|
|
2514
|
+
"5940354580057074848093997050200682056184807770593307860589430076672439820312",
|
|
2515
|
+
"12156638873931618554171829126792193045421052652279363021382169897324752428276"
|
|
2516
|
+
],
|
|
2517
|
+
[
|
|
2518
|
+
"7898200236362823042373859371574133993780991612861777490112507062703164551277",
|
|
2519
|
+
"7074218545237549455313236346927434013100842096812539264420499035217050630853"
|
|
2520
|
+
]
|
|
2473
2521
|
],
|
|
2474
2522
|
[
|
|
2475
|
-
|
|
2476
|
-
|
|
2523
|
+
[
|
|
2524
|
+
"7077479683546002997211712695946002074877511277312570035766170199895071832130",
|
|
2525
|
+
"10093483419865920389913245021038182291233451549023025229112148274109565435465"
|
|
2526
|
+
],
|
|
2527
|
+
[
|
|
2528
|
+
"4595479056700221319381530156280926371456704509942304414423590385166031118820",
|
|
2529
|
+
"19831328484489333784475432780421641293929726139240675179672856274388269393268"
|
|
2530
|
+
],
|
|
2531
|
+
[
|
|
2532
|
+
"11934129596455521040620786944827826205713621633706285934057045369193958244500",
|
|
2533
|
+
"8037395052364110730298837004334506829870972346962140206007064471173334027475"
|
|
2534
|
+
]
|
|
2477
2535
|
]
|
|
2478
2536
|
],
|
|
2479
|
-
[
|
|
2537
|
+
IC: [
|
|
2538
|
+
[
|
|
2539
|
+
"12951059800758687233303204819298121944551181861362200875212570257618182506154",
|
|
2540
|
+
"5751958719396509176593242305268064754837298673622815112953832050159760501392",
|
|
2541
|
+
"1"
|
|
2542
|
+
],
|
|
2480
2543
|
[
|
|
2481
|
-
"
|
|
2482
|
-
"
|
|
2544
|
+
"9561588427935871983444704959674198910445823619407211599507208879011862515257",
|
|
2545
|
+
"14576201570478094842467636169770180675293504492823217349086195663150934064643",
|
|
2546
|
+
"1"
|
|
2483
2547
|
],
|
|
2484
2548
|
[
|
|
2485
|
-
"
|
|
2486
|
-
"
|
|
2549
|
+
"4811967233483727873912563574622036989372099129165459921963463310078093941559",
|
|
2550
|
+
"1874883809855039536107616044787862082553628089593740724610117059083415551067",
|
|
2551
|
+
"1"
|
|
2487
2552
|
],
|
|
2488
2553
|
[
|
|
2489
|
-
"
|
|
2490
|
-
"
|
|
2554
|
+
"12252730267779308452229639835051322390696643456253768618882001876621526827161",
|
|
2555
|
+
"7899194018737016222260328309937800777948677569409898603827268776967707173231",
|
|
2556
|
+
"1"
|
|
2491
2557
|
]
|
|
2492
2558
|
]
|
|
2493
|
-
|
|
2494
|
-
IC: [
|
|
2495
|
-
[
|
|
2496
|
-
"12951059800758687233303204819298121944551181861362200875212570257618182506154",
|
|
2497
|
-
"5751958719396509176593242305268064754837298673622815112953832050159760501392",
|
|
2498
|
-
"1"
|
|
2499
|
-
],
|
|
2500
|
-
[
|
|
2501
|
-
"9561588427935871983444704959674198910445823619407211599507208879011862515257",
|
|
2502
|
-
"14576201570478094842467636169770180675293504492823217349086195663150934064643",
|
|
2503
|
-
"1"
|
|
2504
|
-
],
|
|
2505
|
-
[
|
|
2506
|
-
"4811967233483727873912563574622036989372099129165459921963463310078093941559",
|
|
2507
|
-
"1874883809855039536107616044787862082553628089593740724610117059083415551067",
|
|
2508
|
-
"1"
|
|
2509
|
-
],
|
|
2510
|
-
[
|
|
2511
|
-
"12252730267779308452229639835051322390696643456253768618882001876621526827161",
|
|
2512
|
-
"7899194018737016222260328309937800777948677569409898603827268776967707173231",
|
|
2513
|
-
"1"
|
|
2514
|
-
]
|
|
2515
|
-
]
|
|
2516
|
-
};
|
|
2517
|
-
dotenv.config();
|
|
2518
|
-
const { BANDADA_API_URL, BANDADA_GROUP_ID } = process.env;
|
|
2519
|
-
const bandadaApi = new ApiSdk(BANDADA_API_URL);
|
|
2520
|
-
const bandadaValidateProof = functions
|
|
2521
|
-
.region("europe-west1")
|
|
2522
|
-
.runWith({
|
|
2523
|
-
memory: "512MB"
|
|
2524
|
-
})
|
|
2525
|
-
.https.onCall(async (data) => {
|
|
2559
|
+
};
|
|
2526
2560
|
if (!BANDADA_GROUP_ID)
|
|
2527
2561
|
throw new Error("BANDADA_GROUP_ID is not defined in .env");
|
|
2528
2562
|
const { proof, publicSignals } = data;
|
|
@@ -2683,7 +2717,7 @@ const checkAndRemoveBlockingContributor = functions
|
|
|
2683
2717
|
// Case (A).
|
|
2684
2718
|
if (!currentContributor)
|
|
2685
2719
|
// Do not use `logAndThrowError` method to avoid the function to exit before checking every ceremony.
|
|
2686
|
-
printLog(`No current contributor for circuit ${circuit.id} - ceremony ${ceremony.id}`, LogLevel.
|
|
2720
|
+
printLog(`No current contributor for circuit ${circuit.id} - ceremony ${ceremony.id}`, LogLevel.DEBUG);
|
|
2687
2721
|
else if (avgFullContribution === 0 &&
|
|
2688
2722
|
avgContributionComputation === 0 &&
|
|
2689
2723
|
avgVerifyCloudFunction === 0 &&
|
|
@@ -2709,7 +2743,7 @@ const checkAndRemoveBlockingContributor = functions
|
|
|
2709
2743
|
? Number(contributionStartedAt) +
|
|
2710
2744
|
Number(avgFullContribution) +
|
|
2711
2745
|
Number(timeoutDynamicThreshold)
|
|
2712
|
-
: Number(contributionStartedAt) + Number(fixedTimeWindow) * 60000; // * 60000 = convert minutes to millis.
|
|
2746
|
+
: (Number(contributionStartedAt) + Number(fixedTimeWindow)) * 60000; // * 60000 = convert minutes to millis.
|
|
2713
2747
|
// Case (D).
|
|
2714
2748
|
const timeoutExpirationDateInMsForVerificationCloudFunction = contributionStep === "VERIFYING" /* ParticipantContributionStep.VERIFYING */ &&
|
|
2715
2749
|
!!verificationStartedAt
|
|
@@ -2727,11 +2761,11 @@ const checkAndRemoveBlockingContributor = functions
|
|
|
2727
2761
|
timeoutExpirationDateInMsForVerificationCloudFunction < currentServerTimestamp &&
|
|
2728
2762
|
contributionStep === "VERIFYING" /* ParticipantContributionStep.VERIFYING */)
|
|
2729
2763
|
timeoutType = "BLOCKING_CLOUD_FUNCTION" /* TimeoutType.BLOCKING_CLOUD_FUNCTION */;
|
|
2730
|
-
printLog(`${timeoutType} detected for circuit ${circuit.id} - ceremony ${ceremony.id}`, LogLevel.DEBUG);
|
|
2731
2764
|
if (!timeoutType)
|
|
2732
2765
|
// Do not use `logAndThrowError` method to avoid the function to exit before checking every ceremony.
|
|
2733
|
-
printLog(`No timeout for circuit ${circuit.id} - ceremony ${ceremony.id}`, LogLevel.
|
|
2766
|
+
printLog(`No timeout for circuit ${circuit.id} - ceremony ${ceremony.id}`, LogLevel.DEBUG);
|
|
2734
2767
|
else {
|
|
2768
|
+
printLog(`${timeoutType} detected for circuit ${circuit.id} - ceremony ${ceremony.id}`, LogLevel.WARN);
|
|
2735
2769
|
// Case (E).
|
|
2736
2770
|
let nextCurrentContributorId = "";
|
|
2737
2771
|
// Prepare Firestore batch of txs.
|
|
@@ -2782,7 +2816,7 @@ const checkAndRemoveBlockingContributor = functions
|
|
|
2782
2816
|
});
|
|
2783
2817
|
// Send atomic update for Firestore.
|
|
2784
2818
|
await batch.commit();
|
|
2785
|
-
printLog(`The contributor ${participant.id} has been identified as potential blocking contributor. A timeout of type ${timeoutType} has been triggered w/ a penalty of ${timeoutPenaltyInMs} ms`, LogLevel.
|
|
2819
|
+
printLog(`The contributor ${participant.id} has been identified as potential blocking contributor. A timeout of type ${timeoutType} has been triggered w/ a penalty of ${timeoutPenaltyInMs} ms`, LogLevel.WARN);
|
|
2786
2820
|
}
|
|
2787
2821
|
}
|
|
2788
2822
|
}
|