Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: add qv and non-qv key setup during deploy #1364

Merged
merged 1 commit into from
Apr 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading