@devtion/actions
Version:
A set of actions and helpers for CLI commands
675 lines (632 loc) • 29 kB
text/typescript
import { FirebaseApp } from "firebase/app"
import { DocumentReference, DocumentData, Firestore } from "firebase/firestore"
import { Functions } from "firebase/functions"
import {
CeremonyState,
CeremonyTimeoutType,
CeremonyType,
CircuitContributionVerificationMechanism,
DiskTypeForVM,
ParticipantContributionStep,
ParticipantStatus
} from "./enums.js"
/**
* A shared type that groups all the AWS services variables.
* @typedef {Object} AWSVariables
* @property {string} accessKeyId - the key identifier related to S3 APIs.
* @property {string} secretAccessKey - the secret access key related to S3 APIs.
* @property {string} region - the region where your buckets are located.
* @property {string} instanceProfileArn - the EC2 instance profile the VM should use to access S3.
* @property {string} amiId - the AWS AMI ID (default to Amazon Linux 2).
*/
export type AWSVariables = {
accessKeyId: string
secretAccessKey: string
region: string
instanceProfileArn: string
amiId: string
}
/**
* A shared type that groups all the Firebase services used in the application context.
* @typedef {Object} FirebaseServices
* @property {FirebaseApp} firebaseApp - the instance of the Firebase application.
* @property {Firestore} firestoreDatabase - the instance of the Firestore database in use for the application.
* @property {Functions} firebaseFunctions - the instance of the Cloud Functions in use for the application.
*/
export type FirebaseServices = {
firebaseApp: FirebaseApp
firestoreDatabase: Firestore
firebaseFunctions: Functions
}
/**
* Useful for interacting with reference and data from a Firestore document at the same time.
* @typedef {Object} FirebaseDocumentInfo
* @property {string} id - the unique identifier of the Firestore document.
* @property {DocumentReference<DocumentData>} ref - the Firestore reference for the document (useful for queries).
* @property {DocumentData} data - the Firestore document whole data.
*/
export type FirebaseDocumentInfo = {
id: string
ref: DocumentReference<DocumentData>
data: DocumentData
}
/**
* Define a custom file data chunk associated with a pre-signed url.
* @dev Useful when interacting with AWS S3 buckets using pre-signed urls for multi-part upload or download storing temporary information on the database.
* @typedef {Object} ChunkWithUrl
* @property {number} partNumber - indicate where the chunk is positioned in order to reconhstruct the file with multiPartUpload/Download.
* @property {Buffer} chunk - the piece of information in bytes.
* @property {string} preSignedUrl - the unique reference to the pre-signed url to which this chunk is linked too.
*/
export type ChunkWithUrl = {
partNumber: number
chunk: Buffer
preSignedUrl: string
}
/**
* Group a pre-signed url chunk core information.
* @typedef {Object} ETagWithPartNumber
* @property {string | null} ETag - a unique reference to this chunk associated to a pre-signed url.
* @property {number} PartNumber - indicate where the chunk is positioned in order to reconhstruct the file with multiPartUpload/Download.
*/
export type ETagWithPartNumber = {
ETag: string | undefined
PartNumber: number
}
/**
* Group the information when retrieving the validity of a contribution for a contributor.
* @typedef {Object} ContributionValidity
* @property {string} contributionId - the unique identifier of the contribution.
* @property {string} circuitId - the unique identifier of the circuit for which the contribution was computed.
* @property {boolean} valid - true if and only if the contribution is valid; otherwise false.
*/
export type ContributionValidity = {
contributionId: string
circuitId: string
valid: boolean
}
/**
* Necessary data to define a user database document.
* @typedef {Object} UserDocument
* @property {string} name - the name of the user.
* @property {string | undefined} displayName - the public (visible) name of the user.
* @property {number} creationTime - the timestamp when the document has been created.
* @property {number} lastSignInTime - the timestamp when the user has been authenticated for the last time.
* @property {number} lastUpdated - the timestamp where the last update of the Firestore document has happened.
* @property {string} email - the email of the user.
* @property {boolean} emailVerified - true when the email of the user has been verified; otherwise false.
* @property {string | undefined} photoURL - the external url of the profile photo of the user.
*/
export type UserDocument = {
name: string
displayName: string | undefined
creationTime: number
lastSignInTime: number
lastUpdated: number
email: string
emailVerified: boolean
photoURL: string | undefined
}
/**
* Groups all the information received as input from the coordinator when creating a ceremony.
* @typedef {Object} CeremonyInputData
* @property {string} title - the title/name of the ceremony.
* @property {string} description - a brief description of the ceremony.
* @property {number} startDate - the start (opening to contributions) date for the ceremony (in ms).
* @property {number} endDate - the end (closing to contributions) date for the ceremony (in ms).
* @property {CeremonyTimeoutType} timeoutMechanismType - the timeout mechanism type used for avoiding blocking contribution behaviours.
* @property {number} penalty - the amount of time expressed in minutes that the blocking contributor has to wait before joining the waiting queue again.
*/
export type CeremonyInputData = {
title: string
description: string
startDate: number
endDate: number
timeoutMechanismType: CeremonyTimeoutType
penalty: number
}
/**
* Group information about the version of the Circom compiler used for the ceremony circuits.
* @typedef {Object} CircomCompilerData
* @property {string} version - the version of the Circom compiler.
* @property {string} commitHash - the commit hash of the version of the Circom compiler.
*/
export type CircomCompilerData = {
version: string
commitHash: string
}
/**
* Group information about the Circom circuit template used for the ceremony circuits.
* @dev we are assuming that the circuit template have been published to a public repository (as Github).
* @typedef {Object} SourceTemplateData
* @property {string} source - the external link where the circuit template has been published.
* @property {string} commitHash - the commit hash of the version of the circuit template.
* @property {Array<string>} paramsConfiguration - the list of parameter values used to configure the circuit template (if any).
*/
export type SourceTemplateData = {
source: string
commitHash: string
paramsConfiguration: Array<string>
}
/**
* The references about the artifacts produced during the compilation of the ceremony circuit.
* @typedef {Object} CompilationArtifacts
* @property {string} r1csFilename - the name of the R1CS file.
* @property {string} wasmFilename - the name of the WASM file.
*/
export type CompilationArtifacts = {
r1csFilename: string
wasmFilename: string
}
/**
* Group information about the VM configuration for circuit contribution verification.
* @dev the coordinator could choose among CF and VM.
* @notice the VM configurations could be retrieved at https://aws.amazon.com/ec2/instance-types/.
* @typedef {Object} VMConfiguration
* @property {string} [vmConfigurationType] - the VM configuration type.
* @property {string} [vmDiskType] - the VM volume type (e.g., gp2)
* @property {number} [vmDiskSize] - the VM disk size in GB.
* @property {string} [vmInstanceId] - the VM instance identifier (after VM instantiation).
*/
export type VMConfiguration = {
vmConfigurationType?: string
vmDiskType?: DiskTypeForVM
vmDiskSize?: number
vmInstanceId?: string
}
/**
* Group information about the circuit contribution verification mechanism.
* @typedef {Object} CircuitContributionVerification
* @property {CircuitContributionVerificationMechanism} cfOrVm - the mechanism chosen by the coordinator.
* @property {VMConfiguration} [vm] - the VM configuration specs.
*/
export type CircuitContributionVerification = {
cfOrVm: CircuitContributionVerificationMechanism
vm?: VMConfiguration
}
/**
* Group input data for defining a ceremony circuit.
* @dev The data is both entered by the coordinator and derived.
* @typedef {Object} CircuitInputData
* @property {string} description - a short description for the circuit.
* @property {CircomCompilerData} compiler - the info about the Circom compiler used to compile the circuit template.
* @property {SourceTemplateData} template - the info about the circuit template.
* @property {CircuitContributionVerification} verification - the info about the circuit contribution verification mechanism.
* @property {CompilationArtifacts} compilationArtifacts - the references about the circuit compilation artifacts.
* @property {CircuitMetadata} [metadata] - the info about the R1CS file.
* @property {string} [name] - the name of the circuit.
* @property {number} [dynamicThreshold] - the dynamic timeout threshold expressed in percentage.
* @property {number} [fixedTimeWindow] - the amount of fixed max contribution time which can be spent while contributing before the timeout can be triggered.
* @property {number} [sequencePosition] - the position which define the order of contributions in the ceremony.
* @property {string} [prefix] - the prefix of the circuit derived from the name.
* @property {number} [zKeySizeInBytes] - the size of the related zKey expressed in bytes.
*/
export type CircuitInputData = {
description: string
compiler: CircomCompilerData
template: SourceTemplateData
verification: CircuitContributionVerification
compilationArtifacts?: CompilationArtifacts
metadata?: CircuitMetadata
name?: string
dynamicThreshold?: number
fixedTimeWindow?: number
sequencePosition?: number
prefix?: string
zKeySizeInBytes?: number
}
/**
* Necessary data to define a ceremony database document.
* @dev The data is both entered by the coordinator and derived.
* @typedef {Object} CeremonyDocument
* @property {string} prefix - the prefix of the ceremony derived from the name.
* @property {CeremonyState} state - the current state of the ceremony.
* @property {CeremonyType} type - the type of the ceremony.
* @property {string} coordinatorId - the unique identifier of the coordinator.
* @property {number} lastUpdated - the timestamp where the last update of the Firestore document has happened.
*/
export type CeremonyDocument = CeremonyInputData & {
prefix: string
state: CeremonyState
type: CeremonyType
coordinatorId: string
lastUpdated: number
}
/**
* Data defining a contribution made by a participant.
* @typedef {Object} Contribution
* @property {string} doc - the unique identifier of the document related to the contribution.
* @property {number} computationTime - the overall time spent while computing the contribution.
* @property {string} hash - the contribution hash (generated as output from the snarkjs command).
*/
export type Contribution = {
doc: string
computationTime: number
hash: string
}
/**
* Auxiliary data needed for resumption in an intermediate step of contribution.
* @dev The data is used when the current contributorinterrupts during the download, contribute, upload steps
* to prevent it from having to start over but can pick up where it left off.
* This restart operation does NOT interact with the timeout mechanism (which remains unchanged).
* @typedef {Object} TemporaryParticipantContributionData
* @property {number} contributionComputationTime - the time spent since the contribution start.
* @property {string} uploadId - the unique identifier of the pre-signed url PUT request to upload the newest contribution.
* @property {Array<ETagWithPartNumber>} chunks - the list of ETags and PartNumbers that make up the chunks.
*/
export type TemporaryParticipantContributionData = {
contributionComputationTime: number
uploadId: string
chunks: Array<ETagWithPartNumber>
}
/**
* Necessary data to define a participant database document.
* @typedef {Object} ParticipantDocument
* @property {string} userId - the unique identifier of the user associated with the participant.
* @property {number} contributionProgress - indicates the number of the circuit for which the user has to wait in the queue.
* @property {ParticipantStatus} status - the current status of the participant.
* @property {Array<Contribution>} contributions - the list of references to the contributions computed by the participant.
* @property {number} lastUpdated - the timestamp where the last update of the Firestore document has happened.
* @property {number} [contributionStartedAt] - the timestamp of when the latest contribution has started.
* @property {number} [verificationStartedAt] - the timestamp of when the latest verification process has started.
* @property {TemporaryParticipantContributionData} [tempContributionData] - the auxiliary data needed for resumption in an intermediate step of contribution.
*/
export type ParticipantDocument = {
userId: string
contributionProgress: number
status: ParticipantStatus
contributions: Array<Contribution>
lastUpdated: number
contributionStartedAt: number
contributionStep?: ParticipantContributionStep
verificationStartedAt?: number
tempContributionData?: TemporaryParticipantContributionData
}
/**
* The metadata of a Groth16 circuit.
* @dev The data is derived by reading the R1CS file.
* @typedef {Object} CircuitMetadata
* @property {string} curve - the curve used by the proving system for circuit construction.
* @property {number} wires - the circuit amount of wires among field/gates.
* @property {number} constraints - the amount of constraints (= the size of the circuit).
* @property {number} privateInputs - the amount of private inputs (derived from constraints).
* @property {number} publicInputs - the amount of public inputs (derived from constraints).
* @property {number} labels - the amount of labels.
* @property {number} outputs - the amount of outputs.
* @property {number} pot - the smallest amount of powers needed to work with the circuit (Powers of Tau from Phase 1 setup).
*/
export type CircuitMetadata = {
curve: string
wires: number
constraints: number
privateInputs: number
publicInputs: number
labels: number
outputs: number
pot: number
}
/**
* The references about the artifacts produced during the ceremony for a circuit.
* @dev The references are related to the storage solution used where the files are stored (currently AWS S3).
* @typedef {Object} CircuitArtifacts
* @property {string} potFilename - the name of the Powers of Tau file.
* @property {string} r1csFilename - the name of the R1CS file.
* @property {string} wasmFilename - the name of the WASM file.
* @property {string} initialZkeyFilename - the name of the initial (= genesis) zKey file.
* @property {string} potStoragePath - the storage path of the Powers of Tau file.
* @property {string} r1csStoragePath - the storage path of the R1CS file.
* @property {string} wasmStoragePath - the storage path of the WASM file.
* @property {string} initialZkeyStoragePath - the storage path of the initial (= genesis) zKey file.
* @property {string} potBlake2bHash - the blake2b hash of the Powers of Tau file.
* @property {string} r1csBlake2bHash - the blake2b hash of the R1CS file.
* @property {string} wasmBlake2bHash - the blake2b hash of the WASM file.
* @property {string} initialZkeyBlake2bHash - the blake2b hash of the initial (= genesis) zKey file.
*/
export type CircuitArtifacts = {
potFilename: string
r1csFilename: string
wasmFilename: string
initialZkeyFilename: string
potStoragePath: string
r1csStoragePath: string
wasmStoragePath: string
initialZkeyStoragePath: string
potBlake2bHash: string
r1csBlake2bHash: string
wasmBlake2bHash: string
initialZkeyBlake2bHash: string
}
/**
* The references about the average time spent by contributors on the circuit.
* @typedef {Object} CircuitTimings
* @property {number} contributionComputation - the average amount of time spent for contribution computation only.
* @property {number} fullContribution - the average amount of time spent for the whole contribution.
* @property {number} verifyCloudFunction - the average amount of time spent for verification of contribution only.
*/
export type CircuitTimings = {
contributionComputation: number
fullContribution: number
verifyCloudFunction: number
}
/**
* The information to handle the queue for circuit contributions.
* @typedef {Object} CircuitWaitingQueue
* @property {number} completedContributions - the total amount of completed contributions.
* @property {Array<string>} contributors - the list of unique identifiers of the participants waiting for contributing.
* @property {string} currentContributor - the unique identifier of the participant who is currently contributing.
* @property {number} failedContributions - the total amount of failed contributions.
*/
export type CircuitWaitingQueue = {
completedContributions: number
contributors: Array<string>
currentContributor: string
failedContributions: number
}
/**
* Necessary data to define a circuit database document.
* @typedef {Object} CircuitDocument
* @property {CircuitMetadata} metadata - the info about the circuit metadata.
* @property {CircuitArtifacts} [files] - the references about the circuit artifacts.
* @property {CircuitTimings} [avgTimings] - the info about the average timings for the circuit.
* @property {SourceTemplateData} [template] - the info about the circuit template.
* @property {CircomCompilerData} [compiler] - the info about the circom compiler.
* @property {CircuitWaitingQueue} [waitingQueue] - the info about the circuit waiting queue.
* @property {number} [lastUpdated] - the timestamp where the last update of the Firestore document has happened.
*/
export type CircuitDocument = CircuitInputData & {
metadata?: CircuitMetadata
files?: CircuitArtifacts
avgTimings?: CircuitTimings
template?: SourceTemplateData
compiler?: CircomCompilerData
waitingQueue?: CircuitWaitingQueue
lastUpdated?: number
}
/**
* The references about the artifacts produced during the contribution (either final or not) to a ceremony circuit.
* @dev The references are related to the storage solution used where the files are stored (currently AWS S3).
* @typedef {Object} ContributionFiles
* @property {string} transcriptFilename - the name of the transcript file.
* @property {string} lastZkeyFilename - the name of the contribution (zKey) file.
* @property {string} transcriptStoragePath - the storage path of the transcript file.
* @property {string} lastZkeyStoragePath - the storage path of the contribution (zKey) file.
* @property {string} transcriptBlake2bHash - the blake2b hash of the transcript file.
* @property {string} lastZkeyBlake2bHash - the blake2b hash of the contribution (zKey) file.
* @property {string} [verificationKeyBlake2bHash] - the blake2b hash of the verification key file (final contribution only).
* @property {string} [verificationKeyFilename] - the name of the verification key file (final contribution only).
* @property {string} [verificationKeyStoragePath] - the storage path of the verification key file (final contribution only).
* @property {string} [verifierContractBlake2bHash] - the blake2b hash of the verifier smart contract file (final contribution only).
* @property {string} [verifierContractFilename] - the name of the verifier smart contract file (final contribution only).
* @property {string} [verifierContractStoragePath] - the storage path of the verifier smart contract file (final contribution only).
*/
export type ContributionFiles = {
transcriptFilename: string
lastZkeyFilename: string
transcriptStoragePath: string
lastZkeyStoragePath: string
transcriptBlake2bHash: string
lastZkeyBlake2bHash: string
verificationKeyBlake2bHash?: string
verificationKeyFilename?: string
verificationKeyStoragePath?: string
verifierContractBlake2bHash?: string
verifierContractFilename?: string
verifierContractStoragePath?: string
}
/**
* Group information about the version of the verification software used for contribution verification.
* @typedef {Object} ContributionVerificationSoftware
* @property {string} name - the name of the verification software.
* @property {string} version - the version of the verification software.
* @property {string} commitHash - the commit hash of the version of the verification software.
*/
export type ContributionVerificationSoftware = {
name: string
version: string
commitHash: string
}
/**
* Group information about the value (beacon) used to compute the final contribution while finalizing the ceremony.
* @typedef {Object} BeaconInfo
* @property {string} value - the value of the beacon.
* @property {string} hash - the SHA 256 hash of the beacon.
*/
export type BeaconInfo = {
value: string
hash: string
}
/**
* Necessary data to define a contribution document.
* @typedef {Object} ContributionDocument
* @property {string} participantId - the unique identifier of the contributor.
* @property {number} contributionComputationTime - the amount of time spent for the contribution (download, compute, upload).
* @property {number} verificationComputationTime - the amount of time spent for the verification of the contribution.
* @property {string} zkeyIndex - the index of the contribution.
* @property {ContributionFiles} files - the references and hashes of the artifacts produced during the contribution (and verification).
* @property {ContributionVerificationSoftware} verificationSoftware - the info about the verification software used to verify the contributions.
* @property {boolean} valid - true if the contribution has been evaluated as valid; otherwise false.
* @property {number} lastUpdated - the timestamp where the last update of the Firestore document has happened.
* @property {BeaconInfo} beacon - the data about the value used to compute the final contribution while finalizing the ceremony (final contribution only).
*/
export type ContributionDocument = {
participantId: string
contributionComputationTime: number
verificationComputationTime: number
zkeyIndex: string
files: ContributionFiles
verificationSoftware: ContributionVerificationSoftware
valid: boolean
lastUpdated: number
beacon?: BeaconInfo
}
/**
* Define a circuit document reference and data.
* @dev must be used for generating fake/mock documents when testing.
* @typedef {Object} CircuitDocumentReferenceAndData
* @property {string} uid - the unique identifier of the document.
* @property {CircuitDocument} doc - the info about the circuit document.
*/
export type CircuitDocumentReferenceAndData = {
uid: string
data: CircuitDocument
}
/**
* Define a user document reference and data.
* @dev must be used for generating fake/mock documents when testing.
* @typedef {Object} UserDocumentReferenceAndData
* @property {string} uid - the unique identifier of the document.
* @property {UserDocument} doc - the info about the user document.
*/
export type UserDocumentReferenceAndData = {
uid: string
data: UserDocument
}
/**
* Define a ceremony document reference and data.
* @dev must be used for generating fake/mock documents when testing.
* @typedef {Object} CeremonyDocumentReferenceAndData
* @property {string} uid - the unique identifier of the document.
* @property {CeremonyDocument} doc - the info about the user document.
*/
export type CeremonyDocumentReferenceAndData = {
uid: string
data: CeremonyDocument
}
/**
* Define a participant document reference and data.
* @dev must be used for generating fake/mock documents when testing.
* @typedef {Object} ParticipantDocumentReferenceAndData
* @property {string} uid - the unique identifier of the document.
* @property {ParticipantDocument} doc - the info about the user document.
*/
export type ParticipantDocumentReferenceAndData = {
uid: string
data: ParticipantDocument
}
/**
* Define a ceremony artifacts with their local paths.
* @typedef {Object} CeremonyArtifacts
* @property {string} circuitPrefix - the prefix of the circuit.
* @property {string} circuitId - the unique identifier of the circuit.
* @property {string} directoryRoot - the root directory of the ceremony.
* @property {string} potLocalFilePath - the local path of the pot file.
* @property {string} r1csLocalFilePath - the local path of the r1cs file.
* @property {string} finalZkeyLocalFilePath - the local path of the final zKey file.
* @property {string} lastZkeyLocalFilePath - the local path of the last zKey file.
* @property {string} verifierLocalFilePath - the local path of the verifier file.
* @property {string} verificationKeyLocalFilePath - the local path of the verification key file.
* @property {string} wasmLocalFilePath - the local path of the wasm file.
* @dev must be used for generating fake/mock documents when testing.
*/
export type CeremonyArtifacts = {
circuitPrefix: string
circuitId: string
directoryRoot: string
potLocalFilePath: string
r1csLocalFilePath: string
finalZkeyLocalFilePath: string
lastZkeyLocalFilePath: string
verifierLocalFilePath: string
verificationKeyLocalFilePath: string
wasmLocalFilePath: string
}
/**
* Define a contribution document reference and data.
* @dev must be used for generating fake/mock documents when testing.
* @typedef {Object} ContributionDocumentReferenceAndData
* @property {string} uid - the unique identifier of the document.
* @property {ContributionDocument} doc - the info about the contribution document.
*/
export type ContributionDocumentReferenceAndData = {
uid: string
data: ContributionDocument
}
/**
* Group the details for a VM EC2 instance.
* @typedef {Object} EC2Instance
* @property {string} instanceId - the unique identifier of the VM.
* @property {string} imageId - the unique identifier of the image.
* @property {string} instanceType - the VM type.
* @property {string} keyName - the name of the key.
* @property {string} launchTime - the timestamp of the launch of the VM.
*/
export type EC2Instance = {
instanceId: string
imageId: string
instanceType: string
keyName: string
launchTime: string
}
/**
* Group the information of a Virtual Machine configuration type.
* @typedef {Object} VMConfigurationType
* @property {string} type - the name of the instance type (e.g., t3.small).
* @property {string} ram - the amount of RAM.
* @property {string} vcpu - the number of VCPUs.
*/
export type VMConfigurationType = {
type: string
ram: number
vcpu: number
}
/**
* Group the information required to setup a new ceremony
* @typedef {Object} SetupCeremonyData
* @property {CeremonyInputData} - the details of the ceremony
* @property {string} - the ceremony prefix
* @property {Array<CircuitDocument>} - the details of the circuits
* @property {Array<CeremonyArtifacts>} - the details of the ceremony artifacts
*/
export type SetupCeremonyData = {
ceremonyInputData: CeremonyInputData
ceremonyPrefix: string
circuits: Array<CircuitDocument>
circuitArtifacts: Array<CeremonySetupTemplateCircuitArtifacts>
}
export type CeremonySetupTemplateCircuitArtifacts = {
artifacts: {
bucket: string
region: string
r1csStoragePath: string
wasmStoragePath: string
}
}
export type CeremonySetupTemplateCircuitTimeout = {
dynamicThreshold: number
fixedTimeWindow: number
}
export type CeremonySetupTemplateCircuitName = {
name: string
}
export type CeremonySetupTemplate = {
title: string
description: string
startDate: string
endDate: string
timeoutMechanismType: CeremonyTimeoutType
penalty: number
circuits: Array<
CircuitDocument &
CeremonySetupTemplateCircuitArtifacts &
CeremonySetupTemplateCircuitTimeout &
CeremonySetupTemplateCircuitName
>
}
export type StringifiedBigInts =
| StringifiedBigInts[]
| string
| string[]
| string[][]
| string[][][]
| { [key: string]: StringifiedBigInts }
| null
export type BigIntVariants =
| BigIntVariants[]
| StringifiedBigInts
| bigint
| bigint[]
| bigint[][]
| bigint[][][]
| { [key: string]: BigIntVariants }
| Uint8Array
| null