Skip to content

Commit

Permalink
feat(contracts): tally qv and non-qv optimisations
Browse files Browse the repository at this point in the history
- [x] Remove TallyNonQv and TallyNonQvFactory
- [x] Add non-qv logic to Tally
- [x] Compatibility fixes
  • Loading branch information
0xmad committed Apr 5, 2024
1 parent 4881716 commit b0b7b38
Show file tree
Hide file tree
Showing 36 changed files with 167 additions and 441 deletions.
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 @@ -263,9 +263,9 @@ describe("Stress tests with ceremony params (6,9,2,3)", function test() {

before(async () => {
// deploy the smart contracts
maciAddresses = await deploy({ ...ceremonyDeployArgs, signer, useQv: false });
maciAddresses = await deploy({ ...ceremonyDeployArgs, signer });
// deploy a poll contract
await deployPoll({ ...deployPollArgs, signer });
await deployPoll({ ...deployPollArgs, signer, useQuadraticVoting: false });
});

it("should signup one user", async () => {
Expand Down Expand Up @@ -310,9 +310,9 @@ describe("Stress tests with ceremony params (6,9,2,3)", function test() {

before(async () => {
// deploy the smart contracts
maciAddresses = await deploy({ ...ceremonyDeployArgs, signer, useQv: false });
maciAddresses = await deploy({ ...ceremonyDeployArgs, signer });
// deploy a poll contract
await deployPoll({ ...deployPollArgs, signer });
await deployPoll({ ...deployPollArgs, signer, useQuadraticVoting: false });
});

it("should signup 25 users", async () => {
Expand Down
1 change: 1 addition & 0 deletions cli/tests/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,4 +158,5 @@ export const deployPollArgs: Omit<DeployPollArgs, "signer"> = {
messageTreeDepth: MSG_TREE_DEPTH,
voteOptionTreeDepth: VOTE_OPTION_TREE_DEPTH,
coordinatorPubkey: coordinatorPubKey,
useQuadraticVoting: true,
};
4 changes: 2 additions & 2 deletions cli/tests/e2e/e2e.nonQv.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,9 @@ describe("e2e tests with non quadratic voting", function test() {

before(async () => {
// deploy the smart contracts
maciAddresses = await deploy({ ...deployArgs, signer, useQv: false });
maciAddresses = await deploy({ ...deployArgs, signer });
// deploy a poll contract
await deployPoll({ ...deployPollArgs, signer });
await deployPoll({ ...deployPollArgs, signer, useQuadraticVoting: false });
});

it("should signup one user", async () => {
Expand Down
3 changes: 2 additions & 1 deletion cli/tests/e2e/e2e.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ describe("e2e tests", function test() {
processWasm: testProcessMessagesWasmPath,
tallyWasm: testTallyVotesWasmPath,
useWasm,
useQuadraticVoting: true,
};

// before all tests we deploy the vk registry contract and set the verifying keys
Expand All @@ -111,7 +112,7 @@ describe("e2e tests", function test() {
// deploy the smart contracts
maciAddresses = await deploy({ ...deployArgs, signer });
// deploy a poll contract
pollAddresses = await deployPoll({ ...deployPollArgs, signer });
pollAddresses = await deployPoll({ ...deployPollArgs, signer, useQuadraticVoting: true });
});

it("should signup one user", async () => {
Expand Down
2 changes: 0 additions & 2 deletions cli/ts/commands/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ export const deploy = async ({
poseidonT4Address,
poseidonT5Address,
poseidonT6Address,
useQv = true,
signer,
quiet = true,
}: DeployArgs): Promise<DeployedContracts> => {
Expand Down Expand Up @@ -96,7 +95,6 @@ export const deploy = async ({
signer,
stateTreeDepth,
quiet: true,
useQv,
});

const [maciContractAddress, stateAqContractAddress, pollFactoryContractAddress] = await Promise.all([
Expand Down
2 changes: 2 additions & 0 deletions cli/ts/commands/deployPoll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const deployPoll = async ({
vkRegistryAddress,
signer,
quiet = true,
useQuadraticVoting = false,
}: DeployPollArgs): Promise<PollContracts> => {
banner(quiet);

Expand Down Expand Up @@ -106,6 +107,7 @@ export const deployPoll = async ({
unserializedKey.asContractParam(),
verifierContractAddress,
vkRegistry,
useQuadraticVoting,
{ gasLimit: 10000000 },
);

Expand Down
14 changes: 5 additions & 9 deletions cli/ts/commands/verify.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import {
Tally__factory as TallyFactory,
TallyNonQv__factory as TallyNonQvFactory,
MACI__factory as MACIFactory,
Poll__factory as PollFactory,
Tally,
TallyNonQv,
} from "maci-contracts/typechain-types";
import { hash2, hash3, genTreeCommitment, hashLeftRight } from "maci-crypto";

Expand Down Expand Up @@ -61,9 +58,7 @@ export const verify = async ({

const pollContract = PollFactory.connect(pollAddr, signer);

const tallyContract = useQv
? TallyFactory.connect(tallyContractAddress, signer)
: TallyNonQvFactory.connect(tallyContractAddress, signer);
const tallyContract = TallyFactory.connect(tallyContractAddress, signer);

// verification
const onChainTallyCommitment = BigInt(await tallyContract.tallyCommitment());
Expand Down Expand Up @@ -125,7 +120,7 @@ export const verify = async ({
logGreen(quiet, success("The on-chain tally commitment matches."));

// verify total spent voice credits on-chain
const isValid = await (tallyContract as Tally).verifySpentVoiceCredits(
const isValid = await tallyContract.verifySpentVoiceCredits(
tallyResults.totalSpentVoiceCredits.spent,
tallyResults.totalSpentVoiceCredits.salt,
newResultsCommitment,
Expand All @@ -140,7 +135,7 @@ export const verify = async ({

// verify per vote option voice credits on-chain
const failedSpentCredits = await verifyPerVOSpentVoiceCredits(
tallyContract as Tally,
tallyContract,
tallyResults,
voteOptionTreeDepth,
newSpentVoiceCreditsCommitment,
Expand Down Expand Up @@ -187,10 +182,11 @@ export const verify = async ({
logGreen(quiet, success("The on-chain tally commitment matches."));

// verify total spent voice credits on-chain
const isValid = await (tallyContract as TallyNonQv).verifySpentVoiceCredits(
const isValid = await tallyContract.verifySpentVoiceCredits(
tallyResults.totalSpentVoiceCredits.spent,
tallyResults.totalSpentVoiceCredits.salt,
newResultsCommitment,
0n,
);

if (isValid) {
Expand Down
4 changes: 2 additions & 2 deletions cli/ts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ program
.option("-g, --signupGatekeeperAddress <signupGatekeeperAddress>", "the signup gatekeeper contract address")
.option("-q, --quiet <quiet>", "whether to print values to the console", (value) => value === "true", false)
.option("-r, --rpc-provider <provider>", "the rpc provider URL")
.option("-uq, --use-quadratic-voting", "whether to use quadratic voting", (value) => value === "true", true)
.requiredOption("-s, --stateTreeDepth <stateTreeDepth>", "the state tree depth", parseInt)
.action(async (cmdOptions) => {
try {
Expand All @@ -74,7 +73,6 @@ program
poseidonT4Address: cmdOptions.poseidonT4Address,
poseidonT5Address: cmdOptions.poseidonT5Address,
poseidonT6Address: cmdOptions.poseidonT6Address,
useQv: cmdOptions.useQuadraticVoting,
quiet: cmdOptions.quiet,
signer,
});
Expand Down Expand Up @@ -200,6 +198,7 @@ program
.requiredOption("-m, --msg-tree-depth <messageTreeDepth>", "the message tree depth", parseInt)
.requiredOption("-v, --vote-option-tree-depth <voteOptionTreeDepth>", "the vote option tree depth", parseInt)
.requiredOption("-pk, --pubkey <coordinatorPubkey>", "the coordinator public key")
.option("-uq, --use-quadratic-voting", "whether to use quadratic voting", (value) => value === "true", true)
.option("-x, --maci-address <maciAddress>", "the MACI contract address")
.option("-q, --quiet <quiet>", "whether to print values to the console", (value) => value === "true", false)
.option("-r, --rpc-provider <provider>", "the rpc provider URL")
Expand All @@ -217,6 +216,7 @@ program
maciAddress: cmdObj.maciAddress,
vkRegistryAddress: cmdObj.vkRegistryAddress,
quiet: cmdObj.quiet,
useQuadraticVoting: cmdObj.useQuadraticVoting,
signer,
});
} catch (error) {
Expand Down
10 changes: 5 additions & 5 deletions cli/ts/utils/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -292,11 +292,6 @@ export interface DeployArgs {
* Whether to log the output
*/
quiet?: boolean;

/**
* Whether to use quadratic voting or not
*/
useQv?: boolean;
}

/**
Expand Down Expand Up @@ -352,6 +347,11 @@ export interface DeployPollArgs {
* Whether to log the output to the console
*/
quiet?: boolean;

/**
* Whether to use quadratic voting or not
*/
useQuadraticVoting?: boolean;
}

/**
Expand Down
38 changes: 12 additions & 26 deletions cli/ts/utils/verifiers.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { genTreeProof } from "maci-crypto";

import type { TallyData } from "./interfaces";
import type { Tally, TallyNonQv } from "maci-contracts";
import type { Tally } from "maci-contracts";

/**
* Loop through each per vote option spent voice credits and verify it on-chain
Expand Down Expand Up @@ -57,7 +57,7 @@ export const verifyPerVOSpentVoiceCredits = async (
* @returns list of the indexes of the tally result that failed on-chain verification
*/
export const verifyTallyResults = async (
tallyContract: Tally | TallyNonQv,
tallyContract: Tally,
tallyData: TallyData,
voteOptionTreeDepth: number,
newSpentVoiceCreditsCommitment: bigint,
Expand All @@ -72,30 +72,16 @@ export const verifyTallyResults = async (
voteOptionTreeDepth,
);

let isValid: boolean;

if (!newPerVOSpentVoiceCreditsCommitment) {
// eslint-disable-next-line no-await-in-loop
isValid = await (tallyContract as TallyNonQv).verifyTallyResult(
i,
tallyData.results.tally[i],
proof,
tallyData.results.salt,
voteOptionTreeDepth,
newSpentVoiceCreditsCommitment,
);
} else {
// eslint-disable-next-line no-await-in-loop
isValid = await (tallyContract as Tally).verifyTallyResult(
i,
tallyData.results.tally[i],
proof,
tallyData.results.salt,
voteOptionTreeDepth,
newSpentVoiceCreditsCommitment,
newPerVOSpentVoiceCreditsCommitment,
);
}
// eslint-disable-next-line no-await-in-loop
const isValid = await tallyContract.verifyTallyResult(
i,
tallyData.results.tally[i],
proof,
tallyData.results.salt,
voteOptionTreeDepth,
newSpentVoiceCreditsCommitment,
newPerVOSpentVoiceCreditsCommitment ?? 0n,
);

if (!isValid) {
failedIndices.push(i);
Expand Down
6 changes: 4 additions & 2 deletions contracts/contracts/MACI.sol
Original file line number Diff line number Diff line change
Expand Up @@ -199,13 +199,15 @@ contract MACI is IMACI, Params, Utilities, Ownable {
/// @param _coordinatorPubKey The coordinator's public key
/// @param _verifier The Verifier Contract
/// @param _vkRegistry The VkRegistry Contract
/// @param _isQv Whether to support QV or not
/// @return pollAddr a new Poll contract address
function deployPoll(
uint256 _duration,
TreeDepths memory _treeDepths,
PubKey memory _coordinatorPubKey,
address _verifier,
address _vkRegistry
address _vkRegistry,

Check warning

Code scanning / Slither

Conformance to Solidity naming conventions Warning

bool _isQv
) public virtual onlyOwner returns (PollContracts memory pollAddr) {
// cache the poll to a local variable so we can increment it
uint256 pollId = nextPollId;
Expand Down Expand Up @@ -238,7 +240,7 @@ contract MACI is IMACI, Params, Utilities, Ownable {
);

address mp = messageProcessorFactory.deploy(_verifier, _vkRegistry, p, _owner);
address tally = tallyFactory.deploy(_verifier, _vkRegistry, p, mp, _owner);
address tally = tallyFactory.deploy(_verifier, _vkRegistry, p, mp, _owner, _isQv);

polls[pollId] = p;

Expand Down
Loading

0 comments on commit b0b7b38

Please sign in to comment.