Skip to content

Commit

Permalink
Merge pull request #1364 from privacy-scaling-explorations/chore/depl…
Browse files Browse the repository at this point in the history
…oy-optimisations

chore: add qv and non-qv key setup during deploy
  • Loading branch information
0xmad authored Apr 10, 2024
2 parents f8d8d95 + 29f9e17 commit ca543fe
Show file tree
Hide file tree
Showing 14 changed files with 393 additions and 111 deletions.
4 changes: 2 additions & 2 deletions cli/testScript.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ node build/ts/index.js setVerifyingKeys \
--msg-tree-depth 2 \
--vote-option-tree-depth 2 \
--msg-batch-depth 1 \
--process-messages-zkey ./zkeys/ProcessMessages_10-2-1-2_test/ProcessMessages_10-2-1-2_test.0.zkey \
--tally-votes-zkey ./zkeys/TallyVotes_10-1-2_test/TallyVotes_10-1-2_test.0.zkey
--process-messages-zkey-qv ./zkeys/ProcessMessages_10-2-1-2_test/ProcessMessages_10-2-1-2_test.0.zkey \
--tally-votes-zkey-qv ./zkeys/TallyVotes_10-1-2_test/TallyVotes_10-1-2_test.0.zkey
node build/ts/index.js create -s 10
node build/ts/index.js deployPoll \
--pubkey macipk.281830024fb6d21a4c73a89a7139aff61fbbddad731ef2dc2db9516171fd390e \
Expand Down
8 changes: 4 additions & 4 deletions cli/tests/ceremony-params/ceremonyParams.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ describe("Stress tests with ceremony params (6,9,2,3)", function test() {
messageTreeDepth,
voteOptionTreeDepth,
messageBatchDepth,
processMessagesZkeyPath: ceremonyProcessMessagesZkeyPath,
tallyVotesZkeyPath: ceremonyTallyVotesZkeyPath,
processMessagesZkeyPathQv: ceremonyProcessMessagesZkeyPath,
tallyVotesZkeyPathQv: ceremonyTallyVotesZkeyPath,
};

const verifyingKeysNonQvArgs: Omit<SetVerifyingKeysArgs, "signer"> = {
Expand All @@ -81,8 +81,8 @@ describe("Stress tests with ceremony params (6,9,2,3)", function test() {
messageTreeDepth,
voteOptionTreeDepth,
messageBatchDepth,
processMessagesZkeyPath: ceremonyProcessMessagesNonQvZkeyPath,
tallyVotesZkeyPath: ceremonyTallyVotesNonQvZkeyPath,
processMessagesZkeyPathNonQv: ceremonyProcessMessagesNonQvZkeyPath,
tallyVotesZkeyPathNonQv: ceremonyTallyVotesNonQvZkeyPath,
};

const ceremonyDeployArgs: Omit<DeployArgs, "signer"> = {
Expand Down
8 changes: 4 additions & 4 deletions cli/tests/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ export const setVerifyingKeysArgs: Omit<SetVerifyingKeysArgs, "signer"> = {
messageTreeDepth: MSG_TREE_DEPTH,
voteOptionTreeDepth: VOTE_OPTION_TREE_DEPTH,
messageBatchDepth: MSG_BATCH_DEPTH,
processMessagesZkeyPath: processMessageTestZkeyPath,
tallyVotesZkeyPath: tallyVotesTestZkeyPath,
processMessagesZkeyPathQv: processMessageTestZkeyPath,
tallyVotesZkeyPathQv: tallyVotesTestZkeyPath,
};

export const setVerifyingKeysNonQvArgs: Omit<SetVerifyingKeysArgs, "signer"> = {
Expand All @@ -105,8 +105,8 @@ export const setVerifyingKeysNonQvArgs: Omit<SetVerifyingKeysArgs, "signer"> = {
messageTreeDepth: MSG_TREE_DEPTH,
voteOptionTreeDepth: VOTE_OPTION_TREE_DEPTH,
messageBatchDepth: MSG_BATCH_DEPTH,
processMessagesZkeyPath: processMessageTestNonQvZkeyPath,
tallyVotesZkeyPath: tallyVotesTestNonQvZkeyPath,
processMessagesZkeyPathNonQv: processMessageTestNonQvZkeyPath,
tallyVotesZkeyPathNonQv: tallyVotesTestNonQvZkeyPath,
};

export const checkVerifyingKeysArgs: Omit<CheckVerifyingKeysArgs, "signer"> = {
Expand Down
248 changes: 177 additions & 71 deletions cli/ts/commands/setVerifyingKeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ export const setVerifyingKeys = async ({
messageTreeDepth,
voteOptionTreeDepth,
messageBatchDepth,
processMessagesZkeyPath,
tallyVotesZkeyPath,
processMessagesZkeyPathQv,
tallyVotesZkeyPathQv,
processMessagesZkeyPathNonQv,
tallyVotesZkeyPathNonQv,
vkRegistry,
signer,
useQuadraticVoting = true,
Expand All @@ -48,17 +50,28 @@ export const setVerifyingKeys = async ({
const vkRegistryAddress = vkRegistry || readContractAddress("VkRegistry", network?.name);

// check if zKey files exist
if (!fs.existsSync(processMessagesZkeyPath)) {
logError(`${processMessagesZkeyPath} does not exist.`);
if (useQuadraticVoting && processMessagesZkeyPathQv && !fs.existsSync(processMessagesZkeyPathQv)) {
logError(`${processMessagesZkeyPathQv} does not exist.`);
}

if (useQuadraticVoting && tallyVotesZkeyPathQv && !fs.existsSync(tallyVotesZkeyPathQv)) {
logError(`${tallyVotesZkeyPathQv} does not exist.`);
}

if (!fs.existsSync(tallyVotesZkeyPath)) {
logError(`${tallyVotesZkeyPath} does not exist.`);
if (!useQuadraticVoting && processMessagesZkeyPathNonQv && !fs.existsSync(processMessagesZkeyPathNonQv)) {
logError(`${processMessagesZkeyPathNonQv} does not exist.`);
}

if (!useQuadraticVoting && tallyVotesZkeyPathNonQv && !fs.existsSync(tallyVotesZkeyPathNonQv)) {
logError(`${tallyVotesZkeyPathNonQv} does not exist.`);
}

// extract the vks
const processVk = VerifyingKey.fromObj(await extractVk(processMessagesZkeyPath));
const tallyVk = VerifyingKey.fromObj(await extractVk(tallyVotesZkeyPath));
const processVkQv = processMessagesZkeyPathQv && VerifyingKey.fromObj(await extractVk(processMessagesZkeyPathQv));
const tallyVkQv = tallyVotesZkeyPathQv && VerifyingKey.fromObj(await extractVk(tallyVotesZkeyPathQv));
const processVkNonQv =
processMessagesZkeyPathNonQv && VerifyingKey.fromObj(await extractVk(processMessagesZkeyPathNonQv));
const tallyVkNonQv = tallyVotesZkeyPathNonQv && VerifyingKey.fromObj(await extractVk(tallyVotesZkeyPathNonQv));

// validate args
if (
Expand All @@ -75,41 +88,25 @@ export const setVerifyingKeys = async ({
logError("Invalid state tree depth or intermediate state tree depth");
}

// Check the pm zkey filename against specified params
const pmMatch = processMessagesZkeyPath.match(/.+_(\d+)-(\d+)-(\d+)-(\d+)/);

if (!pmMatch) {
logError(`${processMessagesZkeyPath} has an invalid filename`);
return;
}

const pmStateTreeDepth = Number(pmMatch[1]);
const pmMsgTreeDepth = Number(pmMatch[2]);
const pmMsgBatchDepth = Number(pmMatch[3]);
const pmVoteOptionTreeDepth = Number(pmMatch[4]);

const tvMatch = tallyVotesZkeyPath.match(/.+_(\d+)-(\d+)-(\d+)/);

if (!tvMatch) {
logError(`${tallyVotesZkeyPath} has an invalid filename`);
return;
}

const tvStateTreeDepth = Number(tvMatch[1]);
const tvIntStateTreeDepth = Number(tvMatch[2]);
const tvVoteOptionTreeDepth = Number(tvMatch[3]);

if (
stateTreeDepth !== pmStateTreeDepth ||
messageTreeDepth !== pmMsgTreeDepth ||
messageBatchDepth !== pmMsgBatchDepth ||
voteOptionTreeDepth !== pmVoteOptionTreeDepth ||
stateTreeDepth !== tvStateTreeDepth ||
intStateTreeDepth !== tvIntStateTreeDepth ||
voteOptionTreeDepth !== tvVoteOptionTreeDepth
) {
logError("Incorrect .zkey file; please check the circuit params");
}
checkZkeyFilepaths({
processMessagesZkeyPath: processMessagesZkeyPathQv!,
tallyVotesZkeyPath: tallyVotesZkeyPathQv!,
stateTreeDepth,
messageTreeDepth,
messageBatchDepth,
voteOptionTreeDepth,
intStateTreeDepth,
});

checkZkeyFilepaths({
processMessagesZkeyPath: processMessagesZkeyPathNonQv!,
tallyVotesZkeyPath: tallyVotesZkeyPathNonQv!,
stateTreeDepth,
messageTreeDepth,
messageBatchDepth,
voteOptionTreeDepth,
intStateTreeDepth,
});

// ensure we have a contract deployed at the provided address
if (!(await contractExists(signer.provider!, vkRegistryAddress))) {
Expand All @@ -122,33 +119,57 @@ export const setVerifyingKeys = async ({
const messageBatchSize = 5 ** messageBatchDepth;

// check if the process messages vk was already set
const mode = useQuadraticVoting ? EMode.QV : EMode.NON_QV;
const processVkSig = genProcessVkSig(stateTreeDepth, messageTreeDepth, voteOptionTreeDepth, messageBatchSize);

if (await vkRegistryContract.isProcessVkSet(processVkSig, mode)) {
if (useQuadraticVoting && (await vkRegistryContract.isProcessVkSet(processVkSig, EMode.QV))) {
logError("This process verifying key is already set in the contract");
}

if (!useQuadraticVoting && (await vkRegistryContract.isProcessVkSet(processVkSig, EMode.NON_QV))) {
logError("This process verifying key is already set in the contract");
}

// do the same for the tally votes vk
const tallyVkSig = genTallyVkSig(stateTreeDepth, intStateTreeDepth, voteOptionTreeDepth);

if (await vkRegistryContract.isTallyVkSet(tallyVkSig, mode)) {
if (useQuadraticVoting && (await vkRegistryContract.isTallyVkSet(tallyVkSig, EMode.QV))) {
logError("This tally verifying key is already set in the contract");
}

if (!useQuadraticVoting && (await vkRegistryContract.isTallyVkSet(tallyVkSig, EMode.NON_QV))) {
logError("This tally verifying key is already set in the contract");
}

// actually set those values
try {
logYellow(quiet, info("Setting verifying keys..."));

const processZkeys = [processVkQv, processVkNonQv]
.filter(Boolean)
.map((vk) => (vk as VerifyingKey).asContractParam() as IVerifyingKeyStruct);
const tallyZkeys = [tallyVkQv, tallyVkNonQv]
.filter(Boolean)
.map((vk) => (vk as VerifyingKey).asContractParam() as IVerifyingKeyStruct);
const modes: EMode[] = [];

if (processVkQv && tallyVkQv) {
modes.push(EMode.QV);
}

if (processVkNonQv && tallyVkNonQv) {
modes.push(EMode.NON_QV);
}

// set them onchain
const tx = await vkRegistryContract.setVerifyingKeys(
const tx = await vkRegistryContract.setVerifyingKeysBatch(
stateTreeDepth,
intStateTreeDepth,
messageTreeDepth,
voteOptionTreeDepth,
messageBatchSize,
mode,
processVk.asContractParam() as IVerifyingKeyStruct,
tallyVk.asContractParam() as IVerifyingKeyStruct,
modes,
processZkeys,
tallyZkeys,
);

const receipt = await tx.wait();
Expand All @@ -160,31 +181,116 @@ export const setVerifyingKeys = async ({
logYellow(quiet, info(`Transaction hash: ${receipt!.hash}`));

// confirm that they were actually set correctly
const processVkOnChain = await vkRegistryContract.getProcessVk(
stateTreeDepth,
messageTreeDepth,
voteOptionTreeDepth,
messageBatchSize,
mode,
);

const tallyVkOnChain = await vkRegistryContract.getTallyVk(
stateTreeDepth,
intStateTreeDepth,
voteOptionTreeDepth,
mode,
);

if (!compareVks(processVk, processVkOnChain)) {
logError("processVk mismatch");
}

if (!compareVks(tallyVk, tallyVkOnChain)) {
logError("tallyVk mismatch");
if (useQuadraticVoting) {
const processVkOnChain = await vkRegistryContract.getProcessVk(
stateTreeDepth,
messageTreeDepth,
voteOptionTreeDepth,
messageBatchSize,
EMode.QV,
);

const tallyVkOnChain = await vkRegistryContract.getTallyVk(
stateTreeDepth,
intStateTreeDepth,
voteOptionTreeDepth,
EMode.QV,
);

if (!compareVks(processVkQv as VerifyingKey, processVkOnChain)) {
logError("processVk mismatch");
}

if (!compareVks(tallyVkQv as VerifyingKey, tallyVkOnChain)) {
logError("tallyVk mismatch");
}
} else {
const processVkOnChain = await vkRegistryContract.getProcessVk(
stateTreeDepth,
messageTreeDepth,
voteOptionTreeDepth,
messageBatchSize,
EMode.NON_QV,
);

const tallyVkOnChain = await vkRegistryContract.getTallyVk(
stateTreeDepth,
intStateTreeDepth,
voteOptionTreeDepth,
EMode.NON_QV,
);

if (!compareVks(processVkNonQv as VerifyingKey, processVkOnChain)) {
logError("processVk mismatch");
}

if (!compareVks(tallyVkNonQv as VerifyingKey, tallyVkOnChain)) {
logError("tallyVk mismatch");
}
}
} catch (error) {
logError((error as Error).message);
}

logGreen(quiet, success("Verifying keys set successfully"));
};

interface ICheckZkeyFilepathsArgs {
stateTreeDepth: number;
messageTreeDepth: number;
messageBatchDepth: number;
voteOptionTreeDepth: number;
intStateTreeDepth: number;
processMessagesZkeyPath?: string;
tallyVotesZkeyPath?: string;
}

function checkZkeyFilepaths({
processMessagesZkeyPath,
tallyVotesZkeyPath,
stateTreeDepth,
messageTreeDepth,
messageBatchDepth,
voteOptionTreeDepth,
intStateTreeDepth,
}: ICheckZkeyFilepathsArgs): void {
if (!processMessagesZkeyPath || !tallyVotesZkeyPath) {
return;
}

// Check the pm zkey filename against specified params
const pmMatch = processMessagesZkeyPath.match(/.+_(\d+)-(\d+)-(\d+)-(\d+)/);

if (!pmMatch) {
logError(`${processMessagesZkeyPath} has an invalid filename`);
return;
}

const pmStateTreeDepth = Number(pmMatch[1]);
const pmMsgTreeDepth = Number(pmMatch[2]);
const pmMsgBatchDepth = Number(pmMatch[3]);
const pmVoteOptionTreeDepth = Number(pmMatch[4]);

const tvMatch = tallyVotesZkeyPath.match(/.+_(\d+)-(\d+)-(\d+)/);

if (!tvMatch) {
logError(`${tallyVotesZkeyPath} has an invalid filename`);
return;
}

const tvStateTreeDepth = Number(tvMatch[1]);
const tvIntStateTreeDepth = Number(tvMatch[2]);
const tvVoteOptionTreeDepth = Number(tvMatch[3]);

if (
stateTreeDepth !== pmStateTreeDepth ||
messageTreeDepth !== pmMsgTreeDepth ||
messageBatchDepth !== pmMsgBatchDepth ||
voteOptionTreeDepth !== pmVoteOptionTreeDepth ||
stateTreeDepth !== tvStateTreeDepth ||
intStateTreeDepth !== tvIntStateTreeDepth ||
voteOptionTreeDepth !== tvVoteOptionTreeDepth
) {
logError("Incorrect .zkey file; please check the circuit params");
}
}
Loading

0 comments on commit ca543fe

Please sign in to comment.