Skip to content

Commit

Permalink
refactor: cleanup anon poll joining
Browse files Browse the repository at this point in the history
- [x] Get rid of tally and message processor addresses params for cli
- [x] Return empty ballot roots as param
  • Loading branch information
0xmad committed Dec 3, 2024
1 parent cac7ea8 commit 91e91cf
Show file tree
Hide file tree
Showing 20 changed files with 77 additions and 151 deletions.
19 changes: 5 additions & 14 deletions packages/circuits/circom/core/non-qv/processMessages.circom
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,6 @@ include "../../trees/incrementalQuinaryTree.circom";
var computedCommandsPackedCommandOut[batchSize][PACKED_CMD_LENGTH];

for (var i = 0; i < batchSize; i++) {
var message[MSG_LENGTH];
for (var j = 0; j < MSG_LENGTH; j++) {
message[j] = msgs[i][j];
}
Expand Down Expand Up @@ -290,7 +289,7 @@ template ProcessOneNonQv(stateTreeDepth, voteOptionTreeDepth) {
var STATE_LEAF_TIMESTAMP_IDX = 3;
var N_BITS = 252;

// Inputs representing the message and the current state.
// Number of users that have completed the sign up.
signal input numSignUps;
// The current value of the state tree root.
signal input currentStateRoot;
Expand Down Expand Up @@ -327,11 +326,6 @@ template ProcessOneNonQv(stateTreeDepth, voteOptionTreeDepth) {
signal output newStateRoot;
signal output newBallotRoot;

// Intermediate signals.
// currentVoteWeight * currentVoteWeight.
signal currentVoteWeightSquare;
// cmdNewVoteWeight * cmdNewVoteWeight.
signal cmdNewVoteWeightSquare;
// equal to newBallotVoRootMux (Mux1).
signal newBallotVoRoot;

Expand All @@ -357,7 +351,7 @@ template ProcessOneNonQv(stateTreeDepth, voteOptionTreeDepth) {
packedCmd
);

// 2. If isValid is equal to zero, generate indices for leaf zero.
// 2. If computedIsStateLeafIndexValid is equal to zero, generate indices for leaf zero.
// Otherwise, generate indices for command.stateIndex.
var stateIndexMux = Mux1()([0, cmdStateIndex], computedIsStateLeafIndexValid);
var computedStateLeafPathIndices[stateTreeDepth] = MerkleGeneratePathIndices(stateTreeDepth)(stateIndexMux);
Expand Down Expand Up @@ -389,12 +383,9 @@ template ProcessOneNonQv(stateTreeDepth, voteOptionTreeDepth) {

// 5. Verify that currentVoteWeight exists in the ballot's vote option root
// at cmdVoteOptionIndex.
currentVoteWeightSquare <== currentVoteWeight;
cmdNewVoteWeightSquare <== cmdNewVoteWeight;

var voiceCreditAmountValid = SafeGreaterEqThan(252)([
stateLeaf[STATE_LEAF_VOICE_CREDIT_BALANCE_IDX] + currentVoteWeightSquare,
cmdNewVoteWeightSquare
stateLeaf[STATE_LEAF_VOICE_CREDIT_BALANCE_IDX] + currentVoteWeight,
cmdNewVoteWeight
]);

var cmdVoteOptionIndexMux = Mux1()([0, cmdVoteOptionIndex], computedIsVoteOptionIndexValid);
Expand All @@ -412,7 +403,7 @@ template ProcessOneNonQv(stateTreeDepth, voteOptionTreeDepth) {
var newSlVoiceCreditBalanceMux = Mux1()(
[
stateLeaf[STATE_LEAF_VOICE_CREDIT_BALANCE_IDX],
stateLeaf[STATE_LEAF_VOICE_CREDIT_BALANCE_IDX] + currentVoteWeightSquare - cmdNewVoteWeightSquare
stateLeaf[STATE_LEAF_VOICE_CREDIT_BALANCE_IDX] + currentVoteWeight - cmdNewVoteWeight
],
voiceCreditAmountValid
);
Expand Down
6 changes: 2 additions & 4 deletions packages/circuits/circom/core/qv/processMessages.circom
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,6 @@ template ProcessMessages(
var computedCommandsPackedCommandOut[batchSize][PACKED_CMD_LENGTH];

for (var i = 0; i < batchSize; i++) {
var message[MSG_LENGTH];

for (var j = 0; j < MSG_LENGTH; j++) {
message[j] = msgs[i][j];
}
Expand Down Expand Up @@ -286,7 +284,7 @@ template ProcessOne(stateTreeDepth, voteOptionTreeDepth) {
var STATE_LEAF_TIMESTAMP_IDX = 3;
var N_BITS = 252;

// Inputs representing the message and the current state.
// Number of users that have completed the sign up.
signal input numSignUps;
// The current value of the state tree root.
signal input currentStateRoot;
Expand Down Expand Up @@ -353,7 +351,7 @@ template ProcessOne(stateTreeDepth, voteOptionTreeDepth) {
packedCmd
);

// 2. If isValid is equal to zero, generate indices for leaf zero.
// 2. If computedIsStateLeafIndexValid is equal to zero, generate indices for leaf zero.
// Otherwise, generate indices for command.stateIndex.
var stateIndexMux = Mux1()([0, cmdStateIndex], computedIsStateLeafIndexValid);
var computedStateLeafPathIndices[stateTreeDepth] = MerkleGeneratePathIndices(stateTreeDepth)(stateIndexMux);
Expand Down
1 change: 0 additions & 1 deletion packages/cli/tests/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,6 @@ export const verifyArgs = async (): Promise<Omit<VerifyArgs, "signer">> => {
pollId: 0n,
tallyData,
maciAddress: tallyData.maci,
tallyAddress: tallyData.tallyAddress,
};
};

Expand Down
1 change: 0 additions & 1 deletion packages/cli/tests/e2e/e2e.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,6 @@ describe("e2e tests", function test() {
...(await verifyArgs()),
tallyData: tallyFileData,
maciAddress: tallyFileData.maci,
tallyAddress: tallyFileData.tallyAddress,
signer,
});
});
Expand Down
22 changes: 9 additions & 13 deletions packages/cli/tests/unit/poll.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,10 @@ describe("poll", function test() {
it("should get current poll properly", async () => {
const pollData = await getPoll({
maciAddress: maciAddresses.maciAddress,
tallyAddress: pollAddresses.tally,
signer,
});
const samePollData = await getPoll({
maciAddress: maciAddresses.maciAddress,
tallyAddress: pollAddresses.tally,
pollId: pollData.id,
signer,
});
Expand All @@ -65,7 +63,6 @@ describe("poll", function test() {
it("should get finished poll properly", async () => {
const pollData = await getPoll({
maciAddress: maciAddresses.maciAddress,
tallyAddress: pollAddresses.tally,
provider: signer.provider!,
});

Expand All @@ -74,7 +71,6 @@ describe("poll", function test() {

const finishedPollData = await getPoll({
maciAddress: maciAddresses.maciAddress,
tallyAddress: pollAddresses.tally,
signer,
});

Expand All @@ -84,21 +80,21 @@ describe("poll", function test() {
});

it("should throw error if there are no signer and provider", async () => {
await expect(
getPoll({ maciAddress: maciAddresses.maciAddress, tallyAddress: pollAddresses.tally, pollId: -1n }),
).eventually.rejectedWith("No signer and provider are provided");
await expect(getPoll({ maciAddress: maciAddresses.maciAddress, pollId: -1n })).eventually.rejectedWith(
"No signer and provider are provided",
);
});

it("should throw error if current poll id is invalid", async () => {
await expect(
getPoll({ maciAddress: maciAddresses.maciAddress, tallyAddress: pollAddresses.tally, pollId: -1n, signer }),
).eventually.rejectedWith("Invalid poll id -1");
await expect(getPoll({ maciAddress: maciAddresses.maciAddress, pollId: -1n, signer })).eventually.rejectedWith(
"Invalid poll id -1",
);
});

it("should throw error if current poll is not deployed", async () => {
await expect(
getPoll({ maciAddress: maciAddresses.maciAddress, tallyAddress: pollAddresses.tally, pollId: 9000n, signer }),
).eventually.rejectedWith("MACI contract doesn't have any deployed poll 9000");
await expect(getPoll({ maciAddress: maciAddresses.maciAddress, pollId: 9000n, signer })).eventually.rejectedWith(
"MACI contract doesn't have any deployed poll 9000",
);
});
});
});
6 changes: 1 addition & 5 deletions packages/cli/ts/commands/genProofs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ export const genProofs = async ({
blocksPerBatch,
endBlock,
signer,
tallyAddress,
useQuadraticVoting = true,
quiet = true,
}: GenProofsArgs): Promise<TallyData> => {
Expand Down Expand Up @@ -341,9 +340,6 @@ export const genProofs = async ({
BigInt(asHex(tallyCircuitInputs!.newSpentVoiceCreditSubtotalSalt as BigNumberish)),
);

// get the tally contract address
const tallyContractAddress = tallyAddress || (await readContractAddress(`Tally-${pollId}`, network?.name));

let newPerVOSpentVoiceCreditsCommitment: bigint | undefined;
let newTallyCommitment: bigint;

Expand All @@ -354,7 +350,7 @@ export const genProofs = async ({
network: network?.name,
chainId: network?.chainId.toString(),
isQuadratic: useQuadraticVoting,
tallyAddress: tallyContractAddress,
tallyAddress: pollContracts.tally,
newTallyCommitment: asHex(tallyCircuitInputs!.newTallyCommitment as BigNumberish),
results: {
tally: poll.tallyResult.map((x) => x.toString()),
Expand Down
15 changes: 10 additions & 5 deletions packages/cli/ts/commands/joinPoll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { CircuitInputs, IJsonMaciState, MaciState, IPollJoiningCircuitInputs } f
import { poseidon, stringifyBigInts } from "maci-crypto";
import { IVkObjectParams, Keypair, PrivKey, PubKey, StateLeaf } from "maci-domainobjs";

import assert from "assert";
import fs from "fs";

import type { IJoinPollArgs, IJoinedUserArgs, IParsePollJoinEventsArgs, IJoinPollData } from "../utils";
Expand All @@ -29,7 +28,7 @@ const getStateIndexAndCreditBalance = (
newVoiceCreditBalance: bigint | null,
stateLeaves: StateLeaf[],
userMaciPubKey: PubKey,
) => {
): [bigint | null, bigint | null] => {
let loadedStateIndex = stateIndex;
let loadedCreditBalance = newVoiceCreditBalance;

Expand All @@ -41,6 +40,7 @@ const getStateIndexAndCreditBalance = (
logError("State leaf not found");
}
}

if (!newVoiceCreditBalance) {
const balance = stateLeaves[Number(loadedStateIndex!)].voiceCreditBalance;
if (balance) {
Expand Down Expand Up @@ -72,7 +72,7 @@ const generateAndVerifyProof = async (
witnessExePath: string | undefined,
wasmPath: string | undefined,
pollVk: IVkObjectParams,
) => {
): Promise<string[]> => {
const r = await genProof({
inputs,
zkeyPath,
Expand Down Expand Up @@ -119,7 +119,9 @@ const joiningCircuitInputs = (
const [pubKeyX, pubKeyY] = pubKey.asArray();
const stateLeafArray = [pubKeyX, pubKeyY, voiceCreditBalance, timestamp];

assert(credits <= voiceCreditBalance, "Credits must be lower than signed up credits");
if (credits <= voiceCreditBalance) {
logError("Credits must be lower than signed up credits");
}

// calculate the path elements for the state tree given the original state tree
const { siblings, index } = stateTree.generateProof(Number(stateLeafIndex));
Expand Down Expand Up @@ -386,7 +388,10 @@ const parsePollJoinEvents = async ({
startBlock,
currentBlock,
pollPublicKey,
}: IParsePollJoinEventsArgs) => {
}: IParsePollJoinEventsArgs): Promise<{
pollStateIndex?: string;
voiceCredits?: string;
}> => {
// 1000 blocks at a time
for (let block = startBlock; block <= currentBlock; block += BLOCKS_STEP) {
const toBlock = Math.min(block + BLOCKS_STEP - 1, currentBlock);
Expand Down
3 changes: 1 addition & 2 deletions packages/cli/ts/commands/poll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import { logError, logGreen, success } from "../utils/theme";
*/
export const getPoll = async ({
maciAddress,
tallyAddress,
signer,
provider,
pollId,
Expand Down Expand Up @@ -53,7 +52,7 @@ export const getPoll = async ({
const numSignups = await (isMerged ? pollContract.numSignups() : maciContract.numSignUps());

// get the poll mode
const tallyContract = TallyFactory.connect(tallyAddress, signer ?? provider);
const tallyContract = TallyFactory.connect(pollContracts.tally, signer ?? provider);
const mode = await tallyContract.mode();

logGreen(
Expand Down
27 changes: 2 additions & 25 deletions packages/cli/ts/commands/proveOnChain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ export const proveOnChain = async ({
pollId,
proofDir,
maciAddress,
messageProcessorAddress,
tallyAddress,
tallyFile,
signer,
quiet = true,
Expand All @@ -58,32 +56,11 @@ export const proveOnChain = async ({
logError("MACI contract address is empty");
}

const messageProcessorContractAddress =
messageProcessorAddress || (await readContractAddress(`MessageProcessor-${pollId}`, network?.name));

if (!messageProcessorContractAddress) {
logError("MessageProcessor contract address is empty");
}

const tallyContractAddress = tallyAddress || (await readContractAddress(`Tally-${pollId}`, network?.name));

if (!tallyContractAddress) {
logError("Tally contract address is empty");
}

// check contracts are deployed on chain
if (!(await contractExists(signer.provider!, maciContractAddress))) {
logError("MACI contract does not exist");
}

if (!(await contractExists(signer.provider!, messageProcessorContractAddress))) {
logError("MessageProcessor contract does not exist");
}

if (!(await contractExists(signer.provider!, tallyContractAddress))) {
logError("Tally contract does not exist");
}

const maciContract = MACIFactory.connect(maciContractAddress, signer);
const pollContracts = await maciContract.polls(pollId);

Expand All @@ -93,8 +70,8 @@ export const proveOnChain = async ({

const pollContract = PollFactory.connect(pollContracts.poll, signer);

const mpContract = MessageProcessorFactory.connect(messageProcessorContractAddress, signer);
const tallyContract = TallyFactory.connect(tallyContractAddress, signer);
const mpContract = MessageProcessorFactory.connect(pollContracts.messageProcessor, signer);
const tallyContract = TallyFactory.connect(pollContracts.tally, signer);

const vkRegistryContractAddress = await tallyContract.vkRegistry();

Expand Down
22 changes: 2 additions & 20 deletions packages/cli/ts/commands/verify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,12 @@ import { verifyPerVOSpentVoiceCredits, verifyTallyResults } from "../utils/verif
* Verify the results of a poll on-chain
* @param VerifyArgs - The arguments for the verify command
*/
export const verify = async ({
pollId,
tallyData,
maciAddress,
tallyAddress,
signer,
quiet = true,
}: VerifyArgs): Promise<void> => {
export const verify = async ({ pollId, tallyData, maciAddress, signer, quiet = true }: VerifyArgs): Promise<void> => {
banner(quiet);

const tallyResults = tallyData;
const useQv = tallyResults.isQuadratic;

// we prioritize the tally file data
const tallyContractAddress = tallyResults.tallyAddress || tallyAddress;

if (!tallyContractAddress) {
logError("Tally contract address is empty");
}

if (!(await contractExists(signer.provider!, tallyContractAddress))) {
logError(`Error: there is no Tally contract deployed at ${tallyContractAddress}.`);
}

// prioritize the tally file data
const maciContractAddress = tallyResults.maci || maciAddress;

Expand All @@ -58,7 +40,7 @@ export const verify = async ({

const pollContract = PollFactory.connect(pollContracts.poll, signer);

const tallyContract = TallyFactory.connect(tallyContractAddress, signer);
const tallyContract = TallyFactory.connect(pollContracts.tally, signer);

// verification
const onChainTallyCommitment = BigInt(await tallyContract.tallyCommitment());
Expand Down
Loading

0 comments on commit 91e91cf

Please sign in to comment.