From 52fc7c5b8f2d389868bca6171ffd15a94b1d1659 Mon Sep 17 00:00:00 2001 From: ctrlc03 <93448202+ctrlc03@users.noreply.github.com> Date: Thu, 4 Apr 2024 17:04:33 +0100 Subject: [PATCH] refactor(maci): remove subsidy feature to simplify further protocol improvements The subsidy feature has been removed to simplify further protocol improvements. It will still be available in previous MACI's releases . --- circuits/circom/circuits.json | 6 - circuits/circom/subsidy.circom | 349 ------------ cli/testScript.sh | 4 +- .../ceremony-params/ceremonyParams.test.ts | 13 +- cli/tests/constants.ts | 11 - cli/tests/e2e/e2e.nonQv.test.ts | 4 +- cli/tests/e2e/e2e.subsidy.test.ts | 519 ------------------ cli/tests/e2e/e2e.test.ts | 28 +- cli/tests/e2e/keyChange.test.ts | 8 +- cli/tests/unit/poll.test.ts | 4 +- cli/tests/utils.ts | 14 +- cli/ts/commands/checkVerifyingKeys.ts | 32 -- cli/ts/commands/deployPoll.ts | 14 +- cli/ts/commands/genProofs.ts | 137 +---- cli/ts/commands/proveOnChain.ts | 117 ---- cli/ts/commands/setVerifyingKeys.ts | 64 +-- cli/ts/commands/verify.ts | 53 +- cli/ts/index.ts | 62 +-- cli/ts/sdk/index.ts | 1 - cli/ts/utils/index.ts | 1 - cli/ts/utils/interfaces.ts | 80 --- contracts/contracts/MACI.sol | 24 +- contracts/contracts/Subsidy.sol | 160 ------ contracts/contracts/SubsidyFactory.sol | 23 - contracts/contracts/TallyFactory.sol | 6 +- contracts/contracts/TallyNonQvFactory.sol | 6 +- contracts/contracts/VkRegistry.sol | 89 --- ...lySubsidyFactory.sol => ITallyFactory.sol} | 8 +- .../contracts/interfaces/IVkRegistry.sol | 11 - .../contracts/utilities/CommonUtilities.sol | 4 +- contracts/package.json | 1 - .../deploy/maci/{10-maci.ts => 09-maci.ts} | 4 +- .../tasks/deploy/maci/09-subsidyFactory.ts | 45 -- .../{11-vkRegistry.ts => 10-vkRegistry.ts} | 21 +- contracts/tasks/deploy/poll/01-poll.ts | 22 +- contracts/tasks/helpers/ProofGenerator.ts | 69 +-- contracts/tasks/helpers/Prover.ts | 95 +--- contracts/tasks/helpers/types.ts | 38 -- contracts/tasks/runner/prove.ts | 37 -- contracts/tests/MACI.test.ts | 2 - contracts/tests/MessageProcessor.test.ts | 1 - contracts/tests/Poll.test.ts | 1 - contracts/tests/Subsidy.test.ts | 207 ------- contracts/tests/Tally.test.ts | 3 - contracts/tests/TallyNonQv.test.ts | 1 - contracts/tests/VkRegistry.test.ts | 45 -- contracts/ts/deploy.ts | 30 +- contracts/ts/genMaciState.ts | 1 - core/ts/MaciState.ts | 1 - core/ts/Poll.ts | 205 +------ core/ts/__tests__/Poll.test.ts | 59 -- core/ts/__tests__/utils.test.ts | 12 - core/ts/index.ts | 3 - core/ts/utils/types.ts | 27 - core/ts/utils/utils.ts | 30 - .../ts/__tests__/data/suites.json | 10 +- .../ts/__tests__/integration.test.ts | 50 +- .../ts/__tests__/maci-keys.test.ts | 1 - .../ts/__tests__/utils/interfaces.ts | 15 - integrationTests/ts/__tests__/utils/utils.ts | 20 +- 60 files changed, 72 insertions(+), 2836 deletions(-) delete mode 100644 circuits/circom/subsidy.circom delete mode 100644 cli/tests/e2e/e2e.subsidy.test.ts delete mode 100644 contracts/contracts/Subsidy.sol delete mode 100644 contracts/contracts/SubsidyFactory.sol rename contracts/contracts/interfaces/{ITallySubsidyFactory.sol => ITallyFactory.sol} (72%) rename contracts/tasks/deploy/maci/{10-maci.ts => 09-maci.ts} (95%) delete mode 100644 contracts/tasks/deploy/maci/09-subsidyFactory.ts rename contracts/tasks/deploy/maci/{11-vkRegistry.ts => 10-vkRegistry.ts} (77%) delete mode 100644 contracts/tests/Subsidy.test.ts diff --git a/circuits/circom/circuits.json b/circuits/circom/circuits.json index e397c16669..c422a01ee6 100644 --- a/circuits/circom/circuits.json +++ b/circuits/circom/circuits.json @@ -22,11 +22,5 @@ "template": "TallyVotesNonQv", "params": [10, 1, 2], "pubs": ["inputHash"] - }, - "SubsidyPerBatch_10-1-2_test": { - "file": "subsidy", - "template": "SubsidyPerBatch", - "params": [10, 1, 2], - "pubs": ["inputHash"] } } diff --git a/circuits/circom/subsidy.circom b/circuits/circom/subsidy.circom deleted file mode 100644 index 93caa66796..0000000000 --- a/circuits/circom/subsidy.circom +++ /dev/null @@ -1,349 +0,0 @@ -pragma circom 2.0.0; - -// circomlib import -include "./comparators.circom"; - -// local imports -include "./trees/incrementalQuinTree.circom"; -include "./trees/calculateTotal.circom"; -include "./trees/checkRoot.circom"; -include "./hasherSha256.circom"; -include "./hasherPoseidon.circom"; -include "./unpackElement.circom"; -include "./float.circom"; - -/* - * calculate subsidy, batch by batch. - */ -template SubsidyPerBatch ( - stateTreeDepth, - intStateTreeDepth, - voteOptionTreeDepth -) { - // keep MM < 2 ** 196 to avoid overflow: https://hackmd.io/@chaosma/H1_9xmT2K - var MM = 50; // protocol params should be consistent with MaciState.ts - var WW = 4; // number of decimal in float representation, should consist with MaciState.ts - var NN = 64; // maximum width of bits (10**NN < 2**253) in float division - assert(voteOptionTreeDepth > 0); - assert(intStateTreeDepth > 0); - assert(intStateTreeDepth < stateTreeDepth); - - var TREE_ARITY = 5; - - // The number of ballots in this batch - var batchSize = TREE_ARITY ** intStateTreeDepth; // consistent with MaciState.ts - var numVoteOptions = TREE_ARITY ** voteOptionTreeDepth; - - var BALLOT_LENGTH = 2; - var BALLOT_NONCE_IDX = 0; - var BALLOT_VO_ROOT_IDX = 1; - - signal input stateRoot; - signal input ballotRoot; - - signal input sbSalt; - signal input currentSubsidySalt; - signal input newSubsidySalt; - - // The public input (inputHash) is the hash of the following: - signal input sbCommitment; - signal input currentSubsidyCommitment; - signal input newSubsidyCommitment; - signal input packedVals; - signal input inputHash; // public - - var k = stateTreeDepth - intStateTreeDepth; - - signal input ballots1[batchSize][BALLOT_LENGTH]; - signal input ballots2[batchSize][BALLOT_LENGTH]; - signal input votes1[batchSize][numVoteOptions]; - signal input votes2[batchSize][numVoteOptions]; - signal input ballotPathElements1[k][TREE_ARITY - 1]; - signal input ballotPathElements2[k][TREE_ARITY - 1]; - signal input currentSubsidy[numVoteOptions]; - - - // ----------------------------------------------------------------------- - // Verify sbCommitment - component sbCommitmentHasher = Hasher3(); - sbCommitmentHasher.in[0] <== stateRoot; - sbCommitmentHasher.in[1] <== ballotRoot; - sbCommitmentHasher.in[2] <== sbSalt; - sbCommitmentHasher.hash === sbCommitment; - - // ----------------------------------------------------------------------- - // Verify inputHash - component inputHasher = SubsidyInputHasher(); - inputHasher.sbCommitment <== sbCommitment; - inputHasher.currentSubsidyCommitment <== currentSubsidyCommitment; - inputHasher.newSubsidyCommitment <== newSubsidyCommitment; - inputHasher.packedVals <== packedVals; - inputHasher.hash === inputHash; - - // ----------------------------------------------------------------------- - // Validate rowStartIndex and colStartIndex - // they should be less than numSignUps - signal numSignUps; - signal rowStartIndex; - signal colStartIndex; - - numSignUps <== inputHasher.numSignUps; - rowStartIndex <== inputHasher.rbi * batchSize; - colStartIndex <== inputHasher.cbi * batchSize; - - component validRowIndex = LessEqThan(50); - validRowIndex.in[0] <== rowStartIndex; - validRowIndex.in[1] <== numSignUps; - validRowIndex.out === 1; - - component validColIndex = LessEqThan(50); - validColIndex.in[0] <== colStartIndex; - validColIndex.in[1] <== numSignUps; - validColIndex.out === 1; - - // ----------------------------------------------------------------------- - // Verify both batches belong to the ballot tree - component ballotTreeVerifier1 = BatchMerkleTreeVerifier(stateTreeDepth, intStateTreeDepth, TREE_ARITY); - component ballotHashers1[batchSize]; - for (var i = 0; i < batchSize; i++) { - ballotHashers1[i] = HashLeftRight(); - ballotHashers1[i].left <== ballots1[i][BALLOT_NONCE_IDX]; - ballotHashers1[i].right <== ballots1[i][BALLOT_VO_ROOT_IDX]; - ballotTreeVerifier1.leaves[i] <== ballotHashers1[i].hash; - } - ballotTreeVerifier1.index <== inputHasher.rbi; - ballotTreeVerifier1.root <== ballotRoot; - for (var i = 0; i < k; i++) { - for (var j = 0; j < TREE_ARITY - 1; j++) { - ballotTreeVerifier1.pathElements[i][j] <== ballotPathElements1[i][j]; - } - } - - component ballotTreeVerifier2 = BatchMerkleTreeVerifier(stateTreeDepth, intStateTreeDepth, TREE_ARITY); - component ballotHashers2[batchSize]; - for (var i = 0; i < batchSize; i++) { - ballotHashers2[i] = HashLeftRight(); - ballotHashers2[i].left <== ballots2[i][BALLOT_NONCE_IDX]; - ballotHashers2[i].right <== ballots2[i][BALLOT_VO_ROOT_IDX]; - ballotTreeVerifier2.leaves[i] <== ballotHashers2[i].hash; - } - ballotTreeVerifier2.index <== inputHasher.cbi; - ballotTreeVerifier2.root <== ballotRoot; - for (var i = 0; i < k; i++) { - for (var j = 0; j < TREE_ARITY - 1; j++) { - ballotTreeVerifier2.pathElements[i][j] <== ballotPathElements2[i][j]; - } - } - - - // ----------------------------------------------------------------------- - // Verify the vote option roots - component voteTree1[batchSize]; - for (var i = 0; i < batchSize; i++) { - voteTree1[i] = QuinCheckRoot(voteOptionTreeDepth); - for (var j = 0; j < TREE_ARITY ** voteOptionTreeDepth; j++) { - voteTree1[i].leaves[j] <== votes1[i][j]; - } - voteTree1[i].root === ballots1[i][BALLOT_VO_ROOT_IDX]; - } - component voteTree2[batchSize]; - for (var i = 0; i < batchSize; i++) { - voteTree2[i] = QuinCheckRoot(voteOptionTreeDepth); - for (var j = 0; j < TREE_ARITY ** voteOptionTreeDepth; j++) { - voteTree2[i].leaves[j] <== votes2[i][j]; - } - voteTree2[i].root === ballots2[i][BALLOT_VO_ROOT_IDX]; - } - - - // ----------------------------------------------------------------------- - // calculate coefficients for this batch - signal vsquares[batchSize*batchSize][numVoteOptions]; - component tmp[batchSize*batchSize]; - component kij[batchSize*batchSize]; - var idx = 0; - for (var i = 0; i < batchSize; i++) { - for (var j = 0; j < batchSize; j++) { - tmp[idx] = CalculateTotal(numVoteOptions); - kij[idx] = DivisionFromNormal(WW,NN); - for (var p = 0; p < numVoteOptions; p++) { - vsquares[idx][p] <== votes1[i][p] * votes2[j][p]; - tmp[idx].nums[p] <== vsquares[idx][p]; - } - kij[idx].a <== MM; - kij[idx].b <== MM + tmp[idx].sum; - idx++; - } - } - - // calculate subsidy for this batch - component isFirstBatch = IsZero(); - isFirstBatch.in <== rowStartIndex + colStartIndex; - - component iz = IsZero(); - iz.in <== isFirstBatch.out; - component isDiag = IsZero(); - isDiag.in <== rowStartIndex - colStartIndex; - signal lower[batchSize*(batchSize+1)/2][numVoteOptions]; - - component subsidy1[numVoteOptions]; - component subsidy2[numVoteOptions]; - - for (var p = 0; p < numVoteOptions; p++) { - subsidy1[p] = CalculateTotal(batchSize * (batchSize-1)/2 + 1); - subsidy2[p] = CalculateTotal(batchSize * (batchSize+1)/2); - - // upper triangle of coefficients matrix - var cnt1 = 0; - subsidy1[p].nums[batchSize * (batchSize-1)/2] <== currentSubsidy[p] * iz.out; - for (var i = 0; i < batchSize; i++) { - for (var j = i+1; j < batchSize; j++) { - var idx = i * batchSize + j; - subsidy1[p].nums[cnt1] <== 2 * kij[idx].c * vsquares[idx][p]; - cnt1++; - } - } - - // lower half of coefficients matrix - var cnt2 = 0; - for (var i = 0; i < batchSize; i++) { - for (var j = 0; j <= i; j++) { - var idx = i * batchSize + j; - lower[cnt2][p] <== 2 * kij[idx].c * vsquares[idx][p]; - subsidy2[p].nums[cnt2] <== lower[cnt2][p] * (1 - isDiag.out); - cnt2++; - } - } - } - - // Verify the current and new subsidy results - component rcv = SubsidyCommitmentVerifier(voteOptionTreeDepth); - rcv.isFirstBatch <== isFirstBatch.out; - rcv.currentSubsidyCommitment <== currentSubsidyCommitment; - rcv.newSubsidyCommitment <== newSubsidyCommitment; - rcv.currentSubsidySalt <== currentSubsidySalt; - rcv.newSubsidySalt <== newSubsidySalt; - - for (var i = 0; i < numVoteOptions; i++) { - rcv.currentSubsidy[i] <== currentSubsidy[i]; - rcv.newSubsidy[i] <== subsidy1[i].sum + subsidy2[i].sum; - } - - /* - signal output res[numVoteOptions]; - for (var i = 0; i < numVoteOptions; i++) { - res[i] <== rcv.newSubsidy[i]; - } */ - -} - -/* - * Verifies the commitment to the current results. Also computes and outputs a - * commitment to the new results. - */ -template SubsidyCommitmentVerifier(voteOptionTreeDepth) { - var TREE_ARITY = 5; - var numVoteOptions = TREE_ARITY ** voteOptionTreeDepth; - - // 1 if this is the first batch, and 0 otherwise - signal input isFirstBatch; - signal input currentSubsidyCommitment; - signal input newSubsidyCommitment; - - // Results - signal input currentSubsidy[numVoteOptions]; - signal input currentSubsidySalt; - - signal input newSubsidy[numVoteOptions]; - signal input newSubsidySalt; - - // Compute the commitment to the current results - component currentResultsRoot = QuinCheckRoot(voteOptionTreeDepth); - for (var i = 0; i < numVoteOptions; i++) { - currentResultsRoot.leaves[i] <== currentSubsidy[i]; - } - - component currentResultsCommitment = HashLeftRight(); - currentResultsCommitment.left <== currentResultsRoot.root; - currentResultsCommitment.right <== currentSubsidySalt; - - // Check if the current tally commitment is correct only if this is not the first batch - component iz = IsZero(); - iz.in <== isFirstBatch; - // iz.out is 1 if this is not the first batch - // iz.out is 0 if this is the first batch - - // hz is 0 if this is the first batch - // currentSubsidyCommitment should be 0 if this is the first batch - - // hz is 1 if this is not the first batch - // currentTallyCommitment should not be 0 if this is the first batch - signal hz; - hz <== iz.out * currentResultsCommitment.hash; - hz === currentSubsidyCommitment; - - // Compute the root of the new results - component newResultsRoot = QuinCheckRoot(voteOptionTreeDepth); - for (var i = 0; i < numVoteOptions; i++) { - newResultsRoot.leaves[i] <== newSubsidy[i]; - } - - component newResultsCommitment = HashLeftRight(); - newResultsCommitment.left <== newResultsRoot.root; - newResultsCommitment.right <== newSubsidySalt; - newResultsCommitment.hash === newSubsidyCommitment; -} - - - -template SubsidyInputHasher() { - signal input packedVals; - signal input sbCommitment; - signal input currentSubsidyCommitment; - signal input newSubsidyCommitment; - - signal output numSignUps; - signal output rbi; - signal output cbi; - signal output hash; - - component unpack = UnpackElement(3); - unpack.in <== packedVals; - numSignUps <== unpack.out[0]; - rbi <== unpack.out[1]; - cbi <== unpack.out[2]; - - component hasher = Sha256Hasher4(); - hasher.in[0] <== packedVals; - hasher.in[1] <== sbCommitment; - hasher.in[2] <== currentSubsidyCommitment; - hasher.in[3] <== newSubsidyCommitment; - - hash <== hasher.hash; -} - -template BatchMerkleTreeVerifier(coeffTreeDepth, intCoeffTreeDepth, TREE_ARITY) { - var batchSize = TREE_ARITY ** intCoeffTreeDepth; - // Hash each leaf of the batch and generate the subroot - var k = coeffTreeDepth - intCoeffTreeDepth; - signal input leaves[batchSize]; - signal input pathElements[k][TREE_ARITY - 1]; - signal input root; - signal input index; - component ballotSubroot = QuinCheckRoot(intCoeffTreeDepth); - for (var i = 0; i < batchSize; i++) { - ballotSubroot.leaves[i] <== leaves[i]; - } - - component ballotQle = QuinLeafExists(k); - component upperTreePathIndices = QuinGeneratePathIndices(k); - upperTreePathIndices.in <== index; - ballotQle.leaf <== ballotSubroot.root; - ballotQle.root <== root; - for (var i = 0; i < k; i++) { - ballotQle.path_index[i] <== upperTreePathIndices.out[i]; - for (var j = 0; j < TREE_ARITY - 1; j++) { - ballotQle.path_elements[i][j] <== pathElements[i][j]; - } - } -} diff --git a/cli/testScript.sh b/cli/testScript.sh index a8dc6fede2..8903663594 100755 --- a/cli/testScript.sh +++ b/cli/testScript.sh @@ -53,9 +53,7 @@ node build/ts/index.js genProofs \ -q false node build/ts/index.js proveOnChain \ --poll-id 0 \ - --proof-dir proofs/ \ - --subsidy-enabled false + --proof-dir proofs/ node build/ts/index.js verify \ --poll-id 0 \ - --subsidy-enabled false \ --tally-file tally.json diff --git a/cli/tests/ceremony-params/ceremonyParams.test.ts b/cli/tests/ceremony-params/ceremonyParams.test.ts index 44422c0b90..c07e1433ba 100644 --- a/cli/tests/ceremony-params/ceremonyParams.test.ts +++ b/cli/tests/ceremony-params/ceremonyParams.test.ts @@ -46,7 +46,7 @@ import { ceremonyProcessMessagesNonQvWasmPath, ceremonyTallyVotesNonQvWasmPath, } from "../constants"; -import { cleanVanilla, isArm } from "../utils"; +import { clean, isArm } from "../utils"; describe("Stress tests with ceremony params (6,9,2,3)", function test() { const messageTreeDepth = 9; @@ -57,8 +57,6 @@ describe("Stress tests with ceremony params (6,9,2,3)", function test() { const pollDuration = 60000; - const subsidyEnabled = false; - const useWasm = isArm(); this.timeout(90000000); @@ -98,7 +96,6 @@ describe("Stress tests with ceremony params (6,9,2,3)", function test() { messageTreeDepth, voteOptionTreeDepth, coordinatorPubkey: coordinatorPubKey, - subsidyEnabled, }; const genProofsCeremonyArgs: Omit = { @@ -133,7 +130,7 @@ describe("Stress tests with ceremony params (6,9,2,3)", function test() { describe("1 user, 2 messages", () => { after(() => { - cleanVanilla(); + clean(); }); before(async () => { @@ -180,7 +177,7 @@ describe("Stress tests with ceremony params (6,9,2,3)", function test() { describe("25 signups, 100 messages", () => { after(() => { - cleanVanilla(); + clean(); }); before(async () => { @@ -261,7 +258,7 @@ describe("Stress tests with ceremony params (6,9,2,3)", function test() { describe("1 signup, 1 message", () => { after(() => { - cleanVanilla(); + clean(); }); before(async () => { @@ -308,7 +305,7 @@ describe("Stress tests with ceremony params (6,9,2,3)", function test() { describe("25 signups, 100 messages", () => { after(() => { - cleanVanilla(); + clean(); }); before(async () => { diff --git a/cli/tests/constants.ts b/cli/tests/constants.ts index 3a4b73267e..ca562d759b 100644 --- a/cli/tests/constants.ts +++ b/cli/tests/constants.ts @@ -29,9 +29,7 @@ export const tallyVotesTestZkeyPath = "./zkeys/TallyVotes_10-1-2_test/TallyVotes export const processMessageTestNonQvZkeyPath = "./zkeys/ProcessMessagesNonQv_10-2-1-2_test/ProcessMessagesNonQv_10-2-1-2_test.0.zkey"; export const tallyVotesTestNonQvZkeyPath = "./zkeys/TallyVotesNonQv_10-1-2_test/TallyVotesNonQv_10-1-2_test.0.zkey"; -export const subsidyTestZkeyPath = "./zkeys/SubsidyPerBatch_10-1-2_test/SubsidyPerBatch_10-1-2_test.0.zkey"; export const testTallyFilePath = "./tally.json"; -export const testSubsidyFilePath = "./subsidy.json"; export const testProofsDirPath = "./proofs"; export const testProcessMessagesWitnessPath = "./zkeys/ProcessMessages_10-2-1-2_test/ProcessMessages_10-2-1-2_test_cpp/ProcessMessages_10-2-1-2_test"; @@ -41,16 +39,10 @@ export const testTallyVotesWitnessPath = "./zkeys/TallyVotes_10-1-2_test/TallyVotes_10-1-2_test_cpp/TallyVotes_10-1-2_test"; export const testTallyVotesWitnessDatPath = "./zkeys/TallyVotes_10-1-2_test/TallyVotes_10-1-2_test_cpp/TallyVotes_10-1-2_test.dat"; -export const testSubsidyWitnessPath = - "./zkeys/SubsidyPerBatch_10-1-2_test/SubsidyPerBatch_10-1-2_test_cpp/SubsidyPerBatch_10-1-2_test"; -export const testSubsidyWitnessDatPath = - "./zkeys/SubsidyPerBatch_10-1-2_test/SubsidyPerBatch_10-1-2_test_cpp/SubsidyPerBatch_10-1-2_test.dat"; export const testProcessMessagesWasmPath = "./zkeys/ProcessMessages_10-2-1-2_test/ProcessMessages_10-2-1-2_test_js/ProcessMessages_10-2-1-2_test.wasm"; export const testTallyVotesWasmPath = "./zkeys/TallyVotes_10-1-2_test/TallyVotes_10-1-2_test_js/TallyVotes_10-1-2_test.wasm"; -export const testSubsidyWasmPath = - "./zkeys/SubsidyPerBatch_10-1-2_test/SubsidyPerBatch_10-1-2_test_js/SubsidyPerBatch_10-1-2_test.wasm"; export const testRapidsnarkPath = `${homedir()}/rapidsnark/build/prover`; export const ceremonyProcessMessagesZkeyPath = "./zkeys/ProcessMessages_6-9-2-3/processMessages_6-9-2-3.zkey"; export const ceremonyProcessMessagesNonQvZkeyPath = @@ -142,7 +134,6 @@ export const mergeSignupsArgs: Omit = { export const proveOnChainArgs: Omit = { pollId: 0n, proofDir: testProofsDirPath, - subsidyEnabled: false, }; export const verifyArgs = (): Omit => { @@ -150,7 +141,6 @@ export const verifyArgs = (): Omit => { return { pollId: 0n, - subsidyEnabled: false, tallyData, maciAddress: tallyData.maci, tallyAddress: tallyData.tallyAddress, @@ -168,5 +158,4 @@ export const deployPollArgs: Omit = { messageTreeDepth: MSG_TREE_DEPTH, voteOptionTreeDepth: VOTE_OPTION_TREE_DEPTH, coordinatorPubkey: coordinatorPubKey, - subsidyEnabled: false, }; diff --git a/cli/tests/e2e/e2e.nonQv.test.ts b/cli/tests/e2e/e2e.nonQv.test.ts index b93f399ad6..154b56a7bc 100644 --- a/cli/tests/e2e/e2e.nonQv.test.ts +++ b/cli/tests/e2e/e2e.nonQv.test.ts @@ -41,7 +41,7 @@ import { processMessageTestNonQvZkeyPath, tallyVotesTestNonQvZkeyPath, } from "../constants"; -import { cleanVanilla, isArm } from "../utils"; +import { clean, isArm } from "../utils"; /** Test scenarios: @@ -84,7 +84,7 @@ describe("e2e tests with non quadratic voting", function test() { describe("1 signup, 1 message", () => { after(() => { - cleanVanilla(); + clean(); }); const user = new Keypair(); diff --git a/cli/tests/e2e/e2e.subsidy.test.ts b/cli/tests/e2e/e2e.subsidy.test.ts deleted file mode 100644 index 8c340de582..0000000000 --- a/cli/tests/e2e/e2e.subsidy.test.ts +++ /dev/null @@ -1,519 +0,0 @@ -import { getDefaultSigner } from "maci-contracts"; -import { genRandomSalt } from "maci-crypto"; -import { Keypair } from "maci-domainobjs"; - -import type { Signer } from "ethers"; - -import { - checkVerifyingKeys, - deploy, - deployPoll, - deployVkRegistryContract, - genProofs, - mergeMessages, - mergeSignups, - proveOnChain, - publish, - setVerifyingKeys, - signup, - timeTravel, - verify, -} from "../../ts/commands"; -import { DeployedContracts, GenProofsArgs, PollContracts } from "../../ts/utils"; -import { - coordinatorPrivKey, - verifyArgs, - proveOnChainArgs, - processMessageTestZkeyPath, - subsidyTestZkeyPath, - checkVerifyingKeysArgs, - mergeMessagesArgs, - mergeSignupsArgs, - tallyVotesTestZkeyPath, - testProcessMessagesWasmPath, - testProcessMessagesWitnessDatPath, - testProcessMessagesWitnessPath, - testProofsDirPath, - testRapidsnarkPath, - testSubsidyFilePath, - testSubsidyWasmPath, - testSubsidyWitnessDatPath, - testSubsidyWitnessPath, - testTallyFilePath, - testTallyVotesWasmPath, - testTallyVotesWitnessDatPath, - testTallyVotesWitnessPath, - setVerifyingKeysArgs, - deployArgs, - deployPollArgs, - timeTravelArgs, -} from "../constants"; -import { cleanSubsidy, isArm } from "../utils"; - -describe("e2e with Subsidy tests", function test() { - const useWasm = isArm(); - this.timeout(900000); - - let maciAddresses: DeployedContracts; - let pollAddresses: PollContracts; - let vkRegistryContractAddress: string; - let signer: Signer; - - const subsidyEnabled = true; - deployPollArgs.subsidyEnabled = subsidyEnabled; - - const genProofsArgs: Omit = { - outputDir: testProofsDirPath, - tallyFile: testTallyFilePath, - tallyZkey: tallyVotesTestZkeyPath, - processZkey: processMessageTestZkeyPath, - pollId: 0n, - rapidsnark: testRapidsnarkPath, - processWitgen: testProcessMessagesWitnessPath, - processDatFile: testProcessMessagesWitnessDatPath, - tallyWitgen: testTallyVotesWitnessPath, - tallyDatFile: testTallyVotesWitnessDatPath, - coordinatorPrivKey, - processWasm: testProcessMessagesWasmPath, - tallyWasm: testTallyVotesWasmPath, - useWasm, - subsidyZkey: subsidyTestZkeyPath, - subsidyFile: testSubsidyFilePath, - subsidyWitgen: testSubsidyWitnessPath, - subsidyDatFile: testSubsidyWitnessDatPath, - subsidyWasm: testSubsidyWasmPath, - }; - - before(async () => { - signer = await getDefaultSigner(); - - // we deploy the vk registry contract - vkRegistryContractAddress = await deployVkRegistryContract({ signer }); - // we set the verifying keys - await setVerifyingKeys({ ...setVerifyingKeysArgs, subsidyZkeyPath: subsidyTestZkeyPath, signer }); - }); - - describe("4 signups, 6 messages", () => { - after(() => { - cleanSubsidy(); - }); - - const users = [new Keypair(), new Keypair(), new Keypair(), new Keypair()]; - - before(async () => { - // deploy the smart contracts - maciAddresses = await deploy({ ...deployArgs, signer }); - // deploy a poll contract - pollAddresses = await deployPoll({ ...deployPollArgs, signer }); - }); - - it("should signup four users", async () => { - // eslint-disable-next-line @typescript-eslint/prefer-for-of - for (let i = 0; i < users.length; i += 1) { - // eslint-disable-next-line no-await-in-loop - await signup({ maciAddress: maciAddresses.maciAddress, maciPubKey: users[i].pubKey.serialize(), signer }); - } - }); - - it("should publish six messages", async () => { - await publish({ - maciAddress: maciAddresses.maciAddress, - pubkey: users[0].pubKey.serialize(), - stateIndex: 1n, - voteOptionIndex: 0n, - nonce: 1n, - pollId: 0n, - newVoteWeight: 9n, - salt: genRandomSalt(), - privateKey: users[0].privKey.serialize(), - signer, - }); - - await publish({ - maciAddress: maciAddresses.maciAddress, - pubkey: users[1].pubKey.serialize(), - stateIndex: 2n, - voteOptionIndex: 1n, - nonce: 1n, - pollId: 0n, - newVoteWeight: 9n, - salt: genRandomSalt(), - privateKey: users[1].privKey.serialize(), - signer, - }); - - await publish({ - maciAddress: maciAddresses.maciAddress, - pubkey: users[2].pubKey.serialize(), - stateIndex: 3n, - voteOptionIndex: 2n, - nonce: 1n, - pollId: 0n, - newVoteWeight: 9n, - salt: genRandomSalt(), - privateKey: users[2].privKey.serialize(), - signer, - }); - - await publish({ - maciAddress: maciAddresses.maciAddress, - pubkey: users[3].pubKey.serialize(), - stateIndex: 4n, - voteOptionIndex: 3n, - nonce: 1n, - pollId: 0n, - newVoteWeight: 9n, - salt: genRandomSalt(), - privateKey: users[3].privKey.serialize(), - signer, - }); - - await publish({ - maciAddress: maciAddresses.maciAddress, - pubkey: users[3].pubKey.serialize(), - stateIndex: 4n, - voteOptionIndex: 3n, - nonce: 2n, - pollId: 0n, - newVoteWeight: 9n, - salt: genRandomSalt(), - privateKey: users[3].privKey.serialize(), - signer, - }); - - await publish({ - maciAddress: maciAddresses.maciAddress, - pubkey: users[3].pubKey.serialize(), - stateIndex: 4n, - voteOptionIndex: 3n, - nonce: 3n, - pollId: 0n, - newVoteWeight: 9n, - salt: genRandomSalt(), - privateKey: users[3].privKey.serialize(), - signer, - }); - }); - - it("should generate zk-SNARK proofs and verify them", async () => { - await timeTravel({ ...timeTravelArgs, signer }); - await mergeMessages({ ...mergeMessagesArgs, signer }); - await mergeSignups({ ...mergeSignupsArgs, signer }); - await genProofs({ ...genProofsArgs, signer }); - await proveOnChain({ ...proveOnChainArgs, signer }); - await verify({ ...verifyArgs(), signer }); - }); - }); - - describe("9 signups, 1 message", () => { - after(() => { - cleanSubsidy(); - }); - - const users = [ - new Keypair(), - new Keypair(), - new Keypair(), - new Keypair(), - new Keypair(), - new Keypair(), - new Keypair(), - new Keypair(), - new Keypair(), - ]; - - before(async () => { - // deploy the smart contracts - maciAddresses = await deploy({ ...deployArgs, signer }); - // deploy a poll contract - pollAddresses = await deployPoll({ ...deployPollArgs, signer }); - }); - - it("should signup nine users", async () => { - // eslint-disable-next-line @typescript-eslint/prefer-for-of - for (let i = 0; i < users.length; i += 1) { - // eslint-disable-next-line no-await-in-loop - await signup({ maciAddress: maciAddresses.maciAddress, maciPubKey: users[i].pubKey.serialize(), signer }); - } - }); - - it("should publish one message", async () => { - await publish({ - pubkey: users[0].pubKey.serialize(), - stateIndex: 1n, - voteOptionIndex: 0n, - nonce: 1n, - pollId: 0n, - newVoteWeight: 9n, - maciAddress: maciAddresses.maciAddress, - salt: genRandomSalt(), - privateKey: users[0].privKey.serialize(), - signer, - }); - }); - - it("should generate zk-SNARK proofs and verify them", async () => { - await timeTravel({ ...timeTravelArgs, signer }); - await mergeMessages({ ...mergeMessagesArgs, signer }); - await mergeSignups({ ...mergeSignupsArgs, signer }); - const tallyData = await genProofs({ ...genProofsArgs, signer }); - await proveOnChain({ ...proveOnChainArgs, signer }); - await verify({ ...verifyArgs(), tallyData, signer }); - }); - }); - - describe("8 signups (same key), 12 messages (same message)", () => { - after(() => { - cleanSubsidy(); - }); - - const user = new Keypair(); - - before(async () => { - // deploy the smart contracts - maciAddresses = await deploy({ ...deployArgs, signer }); - // deploy a poll contract - pollAddresses = await deployPoll({ ...deployPollArgs, signer }); - }); - - it("should signup eight users (same pub key)", async () => { - for (let i = 0; i < 8; i += 1) { - // eslint-disable-next-line no-await-in-loop - await signup({ maciAddress: maciAddresses.maciAddress, maciPubKey: user.pubKey.serialize(), signer }); - } - }); - - it("should publish 12 messages with the same nonce", async () => { - for (let i = 0; i < 12; i += 1) { - // eslint-disable-next-line no-await-in-loop - await publish({ - pubkey: user.pubKey.serialize(), - stateIndex: 1n, - voteOptionIndex: 0n, - nonce: 1n, - pollId: 0n, - newVoteWeight: 9n, - maciAddress: maciAddresses.maciAddress, - salt: genRandomSalt(), - privateKey: user.privKey.serialize(), - signer, - }); - } - }); - - it("should generate zk-SNARK proofs and verify them", async () => { - await timeTravel({ ...timeTravelArgs, signer }); - await mergeMessages({ ...mergeMessagesArgs, signer }); - await mergeSignups({ ...mergeSignupsArgs, signer }); - const tallyData = await genProofs({ ...genProofsArgs, signer }); - await proveOnChain({ ...proveOnChainArgs, signer }); - await verify({ ...verifyArgs(), tallyData, signer }); - }); - }); - - describe("multiplePolls2", () => { - const users = [ - new Keypair(), - new Keypair(), - new Keypair(), - new Keypair(), - new Keypair(), - new Keypair(), - new Keypair(), - ]; - - let secondPollAddresses: PollContracts; - - after(() => { - cleanSubsidy(); - }); - - before(async () => { - // deploy the smart contracts - maciAddresses = await deploy({ ...deployArgs, signer }); - }); - - it("should run the first poll", async () => { - // deploy a poll contract - pollAddresses = await deployPoll({ ...deployPollArgs, signer }); - // signup - // eslint-disable-next-line @typescript-eslint/prefer-for-of - for (let i = 0; i < users.length; i += 1) { - // eslint-disable-next-line no-await-in-loop - await signup({ maciAddress: maciAddresses.maciAddress, maciPubKey: users[i].pubKey.serialize(), signer }); - } - // publish - await publish({ - pubkey: users[0].pubKey.serialize(), - stateIndex: 1n, - voteOptionIndex: 0n, - nonce: 1n, - pollId: 0n, - newVoteWeight: 9n, - maciAddress: maciAddresses.maciAddress, - salt: genRandomSalt(), - privateKey: users[0].privKey.serialize(), - signer, - }); - // time travel - await timeTravel({ ...timeTravelArgs, signer }); - // generate proofs - await mergeMessages({ ...mergeMessagesArgs, signer }); - await mergeSignups({ ...mergeSignupsArgs, signer }); - await genProofs({ ...genProofsArgs, signer }); - await proveOnChain({ ...proveOnChainArgs, signer }); - await verify({ ...verifyArgs(), signer }); - cleanSubsidy(); - }); - - it("should deploy two more polls", async () => { - // deploy a poll contract - pollAddresses = await deployPoll({ ...deployPollArgs, signer }); - secondPollAddresses = await deployPoll({ ...deployPollArgs, signer }); - }); - - it("should publish messages to the second poll", async () => { - await publish({ - pubkey: users[0].pubKey.serialize(), - stateIndex: 1n, - voteOptionIndex: 0n, - nonce: 1n, - pollId: 1n, - newVoteWeight: 9n, - maciAddress: maciAddresses.maciAddress, - salt: genRandomSalt(), - privateKey: users[0].privKey.serialize(), - signer, - }); - - await publish({ - pubkey: users[1].pubKey.serialize(), - stateIndex: 2n, - voteOptionIndex: 3n, - nonce: 1n, - pollId: 1n, - newVoteWeight: 1n, - maciAddress: maciAddresses.maciAddress, - salt: genRandomSalt(), - privateKey: users[1].privKey.serialize(), - signer, - }); - - await publish({ - pubkey: users[2].pubKey.serialize(), - stateIndex: 3n, - voteOptionIndex: 5n, - nonce: 1n, - pollId: 1n, - newVoteWeight: 3n, - maciAddress: maciAddresses.maciAddress, - salt: genRandomSalt(), - privateKey: users[2].privKey.serialize(), - signer, - }); - }); - - it("should publish messages to the third poll", async () => { - await publish({ - pubkey: users[3].pubKey.serialize(), - stateIndex: 3n, - voteOptionIndex: 5n, - nonce: 1n, - pollId: 2n, - newVoteWeight: 3n, - maciAddress: maciAddresses.maciAddress, - salt: genRandomSalt(), - privateKey: users[3].privKey.serialize(), - signer, - }); - - await publish({ - pubkey: users[4].pubKey.serialize(), - stateIndex: 4n, - voteOptionIndex: 7n, - nonce: 1n, - pollId: 2n, - newVoteWeight: 2n, - maciAddress: maciAddresses.maciAddress, - salt: genRandomSalt(), - privateKey: users[4].privKey.serialize(), - signer, - }); - - await publish({ - pubkey: users[5].pubKey.serialize(), - stateIndex: 5n, - voteOptionIndex: 5n, - nonce: 1n, - pollId: 2n, - newVoteWeight: 9n, - maciAddress: maciAddresses.maciAddress, - salt: genRandomSalt(), - privateKey: users[5].privKey.serialize(), - signer, - }); - }); - - it("should complete the second poll", async () => { - await timeTravel({ ...timeTravelArgs, signer }); - await mergeMessages({ pollId: 1n, signer }); - await mergeSignups({ pollId: 1n, signer }); - const tallyData = await genProofs({ - ...genProofsArgs, - pollId: 1n, - signer, - }); - await proveOnChain({ - ...proveOnChainArgs, - pollId: 1n, - signer, - }); - await verify({ - ...verifyArgs(), - pollId: 1n, - tallyData, - tallyAddress: pollAddresses.tally, - signer, - }); - cleanSubsidy(); - }); - - it("should complete the third poll", async () => { - await mergeMessages({ pollId: 2n, signer }); - await mergeSignups({ pollId: 2n, signer }); - const tallyData = await genProofs({ - ...genProofsArgs, - pollId: 2n, - signer, - }); - await proveOnChain({ - ...proveOnChainArgs, - pollId: 2n, - signer, - }); - await verify({ - ...verifyArgs(), - pollId: 2n, - tallyData, - tallyAddress: secondPollAddresses.tally, - signer, - }); - }); - }); - - describe("checkKeys", () => { - before(async () => { - // deploy maci as we need the address - await deploy({ ...deployArgs, signer }); - }); - - it("should check if the verifying keys have been set correctly", async () => { - await checkVerifyingKeys({ - ...checkVerifyingKeysArgs, - vkRegistry: vkRegistryContractAddress, - subsidyZkeyPath: subsidyTestZkeyPath, - signer, - }); - }); - }); -}); diff --git a/cli/tests/e2e/e2e.test.ts b/cli/tests/e2e/e2e.test.ts index 381aa3d8a0..39805691ce 100644 --- a/cli/tests/e2e/e2e.test.ts +++ b/cli/tests/e2e/e2e.test.ts @@ -51,7 +51,7 @@ import { deployArgs, timeTravelArgs, } from "../constants"; -import { cleanVanilla, isArm } from "../utils"; +import { clean, isArm } from "../utils"; /** Test scenarios: @@ -102,7 +102,7 @@ describe("e2e tests", function test() { describe("1 signup, 1 message", () => { after(() => { - cleanVanilla(); + clean(); }); const user = new Keypair(); @@ -149,7 +149,7 @@ describe("e2e tests", function test() { describe("2 signups (1 after stateAq is merged and logs are fetched), 1 message", () => { after(() => { - cleanVanilla(); + clean(); }); const user = new Keypair(); @@ -199,7 +199,7 @@ describe("e2e tests", function test() { describe("4 signups, 8 messages", () => { after(() => { - cleanVanilla(); + clean(); }); const users = [new Keypair(), new Keypair(), new Keypair(), new Keypair()]; @@ -330,7 +330,7 @@ describe("e2e tests", function test() { describe("5 signups, 1 message", () => { after(() => { - cleanVanilla(); + clean(); }); const users = [ @@ -387,7 +387,7 @@ describe("e2e tests", function test() { describe("8 signups (same key), 12 messages (same message)", () => { after(() => { - cleanVanilla(); + clean(); }); const user = new Keypair(); @@ -436,7 +436,7 @@ describe("e2e tests", function test() { describe("30 signups (31 ballots), 4 messages", () => { after(() => { - cleanVanilla(); + clean(); }); const users = Array.from({ length: 30 }, () => new Keypair()); @@ -533,7 +533,7 @@ describe("e2e tests", function test() { describe("multiplePolls1", () => { after(() => { - cleanVanilla(); + clean(); }); const user = new Keypair(); @@ -566,7 +566,7 @@ describe("e2e tests", function test() { const tallyFileData = await genProofs({ ...genProofsArgs, signer }); await proveOnChain({ ...proveOnChainArgs, signer }); await verify({ ...verifyArgs(), tallyData: tallyFileData, signer }); - cleanVanilla(); + clean(); }); it("should deploy a new poll", async () => { @@ -612,7 +612,7 @@ describe("e2e tests", function test() { let secondPollAddresses: PollContracts; after(() => { - cleanVanilla(); + clean(); }); before(async () => { @@ -663,7 +663,7 @@ describe("e2e tests", function test() { await genProofs({ ...genProofsArgs, signer }); await proveOnChain({ ...proveOnChainArgs, signer }); await verify({ ...verifyArgs(), signer }); - cleanVanilla(); + clean(); }); it("should deploy two more polls", async () => { @@ -775,7 +775,7 @@ describe("e2e tests", function test() { tallyAddress: pollAddresses.tally, signer, }); - cleanVanilla(); + clean(); }); it("should complete the third poll", async () => { @@ -807,7 +807,7 @@ describe("e2e tests", function test() { const user = new Keypair(); after(() => { - cleanVanilla(); + clean(); if (fs.existsSync(stateOutPath)) { fs.unlinkSync(stateOutPath); @@ -867,7 +867,7 @@ describe("e2e tests", function test() { let stateIndex: bigint | undefined; after(() => { - cleanVanilla(); + clean(); }); before(async () => { diff --git a/cli/tests/e2e/keyChange.test.ts b/cli/tests/e2e/keyChange.test.ts index 65f030a296..a7b0c0628f 100644 --- a/cli/tests/e2e/keyChange.test.ts +++ b/cli/tests/e2e/keyChange.test.ts @@ -45,7 +45,7 @@ import { verifyArgs, timeTravelArgs, } from "../constants"; -import { cleanVanilla, isArm } from "../utils"; +import { clean, isArm } from "../utils"; describe("keyChange tests", function test() { const useWasm = isArm(); @@ -85,7 +85,7 @@ describe("keyChange tests", function test() { describe("keyChange and new vote (new vote has same nonce)", () => { after(() => { - cleanVanilla(); + clean(); }); const keypair1 = new Keypair(); @@ -155,7 +155,7 @@ describe("keyChange tests", function test() { describe("keyChange and new vote (new vote has greater nonce and different vote option)", () => { after(() => { - cleanVanilla(); + clean(); }); const keypair1 = new Keypair(); @@ -225,7 +225,7 @@ describe("keyChange tests", function test() { describe("keyChange and new vote (new vote has same nonce and different vote option)", () => { after(() => { - cleanVanilla(); + clean(); }); const keypair1 = new Keypair(); diff --git a/cli/tests/unit/poll.test.ts b/cli/tests/unit/poll.test.ts index f357805344..7c6700dc65 100644 --- a/cli/tests/unit/poll.test.ts +++ b/cli/tests/unit/poll.test.ts @@ -15,7 +15,7 @@ import { } from "../../ts/commands"; import { DeployedContracts, PollContracts } from "../../ts/utils"; import { deployPollArgs, setVerifyingKeysArgs, deployArgs } from "../constants"; -import { cleanVanilla } from "../utils"; +import { clean } from "../utils"; describe("poll", () => { let maciAddresses: DeployedContracts; @@ -34,7 +34,7 @@ describe("poll", () => { describe("check deploy and get poll", () => { after(() => { - cleanVanilla(); + clean(); }); before(async () => { diff --git a/cli/tests/utils.ts b/cli/tests/utils.ts index 707420f9a0..36de8c346f 100644 --- a/cli/tests/utils.ts +++ b/cli/tests/utils.ts @@ -6,7 +6,7 @@ import path from "path"; * Test utility to clean up the proofs directory * and the tally.json file */ -export const cleanVanilla = (): void => { +export const clean = (): void => { const files = fs.readdirSync("./proofs"); files.forEach((file) => { @@ -18,18 +18,6 @@ export const cleanVanilla = (): void => { } }; -/** - * Test utility to clean up the proofs directory - * and the subsidy.json file - */ -export const cleanSubsidy = (): void => { - cleanVanilla(); - - if (fs.existsSync("./subsidy.json")) { - fs.rmSync("./subsidy.json"); - } -}; - /** * Check if we are running on an arm chip * @returns whether we are running on an arm chip diff --git a/cli/ts/commands/checkVerifyingKeys.ts b/cli/ts/commands/checkVerifyingKeys.ts index a5eb6feaa4..82b884b79e 100644 --- a/cli/ts/commands/checkVerifyingKeys.ts +++ b/cli/ts/commands/checkVerifyingKeys.ts @@ -1,6 +1,5 @@ import { extractVk } from "maci-circuits"; import { VkRegistry__factory as VkRegistryFactory } from "maci-contracts"; -import { G1Point, G2Point } from "maci-crypto"; import { VerifyingKey } from "maci-domainobjs"; import fs from "fs"; @@ -34,7 +33,6 @@ export const checkVerifyingKeys = async ({ processMessagesZkeyPath, tallyVotesZkeyPath, vkRegistry, - subsidyZkeyPath, signer, quiet = true, }: CheckVerifyingKeysArgs): Promise => { @@ -67,15 +65,6 @@ export const checkVerifyingKeys = async ({ const processVk = VerifyingKey.fromObj(await extractVk(processMessagesZkeyPath)); const tallyVk = VerifyingKey.fromObj(await extractVk(tallyVotesZkeyPath)); - // check the subsidy key - let subsidyVk: VerifyingKey | undefined; - if (subsidyZkeyPath) { - if (!fs.existsSync(subsidyZkeyPath)) { - logError("The provided Subsidy zkey does not exist"); - } - subsidyVk = VerifyingKey.fromObj(await extractVk(subsidyZkeyPath)); - } - try { logYellow(quiet, info("Retrieving verifying keys from the contract...")); // retrieve the verifying keys from the contract @@ -94,23 +83,6 @@ export const checkVerifyingKeys = async ({ voteOptionTreeDepth, ); - let subsidyVkOnChain: VerifyingKey | undefined; - - if (subsidyVk) { - subsidyVkOnChain = await vkRegistryContractInstance - .getSubsidyVk(stateTreeDepth, intStateTreeDepth, voteOptionTreeDepth) - .then( - ({ alpha1, beta2, gamma2, delta2, ic }) => - new VerifyingKey( - new G1Point(alpha1.x, alpha1.y), - new G2Point(beta2.x, beta2.y), - new G2Point(gamma2.x, gamma2.y), - new G2Point(delta2.x, delta2.y), - ic.map(({ x, y }) => new G1Point(x, y)), - ), - ); - } - // do the actual validation if (!compareVks(processVk, processVkOnChain)) { logError("Process verifying keys do not match"); @@ -119,10 +91,6 @@ export const checkVerifyingKeys = async ({ if (!compareVks(tallyVk, tallyVkOnChain)) { logError("Tally verifying keys do not match"); } - - if (subsidyVk && !compareVks(subsidyVk, subsidyVkOnChain!)) { - logError("Subsidy verifying keys do not match"); - } } catch (error) { logError((error as Error).message); } diff --git a/cli/ts/commands/deployPoll.ts b/cli/ts/commands/deployPoll.ts index bfbae295af..422de686a7 100644 --- a/cli/ts/commands/deployPoll.ts +++ b/cli/ts/commands/deployPoll.ts @@ -25,7 +25,6 @@ export const deployPoll = async ({ messageTreeDepth, voteOptionTreeDepth, coordinatorPubkey, - subsidyEnabled, maciAddress, vkRegistryAddress, signer, @@ -93,7 +92,6 @@ export const deployPoll = async ({ let pollAddr = ""; let messageProcessorContractAddress = ""; let tallyContractAddress = ""; - let subsidyContractAddress; try { // deploy the poll contract via the maci contract @@ -108,7 +106,6 @@ export const deployPoll = async ({ unserializedKey.asContractParam(), verifierContractAddress, vkRegistry, - subsidyEnabled, { gasLimit: 10000000 }, ); @@ -129,7 +126,6 @@ export const deployPoll = async ({ poll: string; messageProcessor: string; tally: string; - subsidy: string; }; }; name: string; @@ -147,18 +143,11 @@ export const deployPoll = async ({ messageProcessorContractAddress = log.args.pollAddr.messageProcessor; tallyContractAddress = log.args.pollAddr.tally; - if (subsidyEnabled) { - subsidyContractAddress = log.args.pollAddr.subsidy; - } - logGreen(quiet, info(`Poll ID: ${pollId.toString()}`)); logGreen(quiet, info(`Poll contract: ${pollAddr}`)); logGreen(quiet, info(`Message Processor contract: ${messageProcessorContractAddress}`)); logGreen(quiet, info(`Tally contract: ${tallyContractAddress}`)); - if (subsidyEnabled && subsidyContractAddress) { - logGreen(quiet, info(`Subsidy contract: ${subsidyContractAddress}`)); - storeContractAddress(`Subsidy-${pollId.toString()}`, subsidyContractAddress, network?.name); - } + // store the address storeContractAddress(`MessageProcessor-${pollId.toString()}`, messageProcessorContractAddress, network?.name); storeContractAddress(`Tally-${pollId.toString()}`, tallyContractAddress, network?.name); @@ -171,7 +160,6 @@ export const deployPoll = async ({ return { messageProcessor: messageProcessorContractAddress, tally: tallyContractAddress, - subsidy: subsidyContractAddress, poll: pollAddr, }; }; diff --git a/cli/ts/commands/genProofs.ts b/cli/ts/commands/genProofs.ts index 2d8be7b1f9..3118f7febd 100644 --- a/cli/ts/commands/genProofs.ts +++ b/cli/ts/commands/genProofs.ts @@ -15,7 +15,6 @@ import path from "path"; import type { BigNumberish } from "ethers"; import { - DEFAULT_ETH_PROVIDER, asHex, banner, contractExists, @@ -30,11 +29,10 @@ import { type Proof, type TallyData, type GenProofsArgs, - type ISnarkJSVerificationKey, } from "../utils"; /** - * Generate proofs for the message processing, tally and subsidy calculations + * Generate proofs for the message processing and tally calculations * @note see different options for zkey files to use specific circuits https://maci.pse.dev/docs/trusted-setup, https://maci.pse.dev/docs/testing/#pre-compiled-artifacts-for-testing * @param GenProofsArgs - The arguments for the genProofs command * @returns The tally data @@ -45,21 +43,16 @@ export const genProofs = async ({ tallyZkey, processZkey, pollId, - subsidyFile, - subsidyZkey, rapidsnark, processWitgen, processDatFile, tallyWitgen, tallyDatFile, - subsidyWitgen, - subsidyDatFile, coordinatorPrivKey, maciAddress, transactionHash, processWasm, tallyWasm, - subsidyWasm, useWasm, stateFile, startBlock, @@ -122,55 +115,6 @@ export const genProofs = async ({ logError(`Could not find ${zkResult[1]}.`); } - // the vk for the subsidy contract (optional) - let subsidyVk: ISnarkJSVerificationKey; - if (subsidyFile) { - if (fs.existsSync(subsidyFile)) { - logError(`${subsidyFile} exists. Please specify a different filepath.`); - } - - if (!subsidyZkey) { - logError("Please specify the subsidy zkey file location"); - } - - if (!subsidyWitgen) { - logError("Please specify the subsidy witnessgen file location"); - } - - // we need different artifacts if using wasm or rapidsnark - if (!useWasm) { - if (!subsidyWitgen) { - logError("Please specify the subsidy witnessgen file location"); - } - - const subsidyWitgenResult = doesPathExist([subsidyWitgen!, subsidyDatFile!]); - - if (!subsidyWitgenResult[0]) { - logError(`Could not find ${subsidyWitgenResult[1]}.`); - } - } else { - // we expect to have the wasm file - if (!subsidyWasm) { - logError("Please specify the subsidy wasm file location"); - } - - const subsidyWasmResult = doesPathExist([subsidyWasm!]); - - if (!subsidyWasmResult[0]) { - logError(`Could not find ${subsidyWasmResult[1]}.`); - } - } - - // either way we check the subsidy zkey - const subsidyZkeyResult = doesPathExist([subsidyZkey!]); - - if (!subsidyZkeyResult[0]) { - logError(`Could not find ${subsidyZkeyResult[1]}.`); - } - - subsidyVk = await extractVk(subsidyZkey!); - } - // extract the rest of the verifying keys const processVk = await extractVk(processZkey); const tallyVk = await extractVk(tallyZkey); @@ -282,7 +226,6 @@ export const genProofs = async ({ const processProofs: Proof[] = []; const tallyProofs: Proof[] = []; - const subsidyProofs: Proof[] = []; // time how long it takes const startTime = Date.now(); @@ -341,84 +284,6 @@ export const genProofs = async ({ logYellow(quiet, info(`gen processMessage proof took ${(endTime - startTime) / 1000} seconds\n`)); - // subsidy calculations are not mandatory - if (subsidyFile) { - const subsidyStartTime = Date.now(); - - logYellow(quiet, info(`Generating proofs of subsidy calculation...`)); - - const { subsidyBatchSize } = poll.batchSizes; - const numLeaves = poll.stateLeaves.length; - const totalSubsidyBatches = Math.ceil(numLeaves / subsidyBatchSize) ** 2; - - logYellow( - quiet, - info(`subsidyBatchSize=${subsidyBatchSize}, numLeaves=${numLeaves}, totalSubsidyBatch=${totalSubsidyBatches}`), - ); - - let numBatchesCalulated = 0; - - let subsidyCircuitInputs: CircuitInputs; - // calculate the subsidy for each batch - while (poll.hasUnfinishedSubsidyCalculation()) { - // calculate subsidy in batches - subsidyCircuitInputs = poll.subsidyPerBatch() as unknown as CircuitInputs; - try { - // generate proof for this batch - // eslint-disable-next-line no-await-in-loop - const r = await genProof({ - inputs: subsidyCircuitInputs, - zkeyPath: subsidyZkey!, - useWasm, - rapidsnarkExePath: rapidsnark, - witnessExePath: subsidyWitgen, - wasmPath: subsidyWasm, - }); - // check validity of it - // eslint-disable-next-line no-await-in-loop - const isValid = await verifyProof(r.publicSignals, r.proof, subsidyVk!); - if (!isValid) { - logError("Error: generated an invalid subsidy calc proof"); - } - - const thisProof = { - circuitInputs: subsidyCircuitInputs, - proof: r.proof, - publicInputs: r.publicSignals, - }; - subsidyProofs.push(thisProof); - fs.writeFileSync( - path.resolve(outputDir, `subsidy_${numBatchesCalulated}.json`), - JSON.stringify(thisProof, null, 4), - ); - numBatchesCalulated += 1; - - logYellow(quiet, info(`Progress: ${numBatchesCalulated} / ${totalSubsidyBatches}`)); - } catch (error) { - logError((error as Error).message); - } - } - - const subsidyFileData = { - provider: process.env.ETH_PROVIDER || DEFAULT_ETH_PROVIDER, - maci: maciAddress, - pollId: pollId.toString(), - newSubsidyCommitment: asHex(subsidyCircuitInputs!.newSubsidyCommitment as BigNumberish), - results: { - subsidy: poll.subsidy.map((x) => x.toString()), - salt: asHex(subsidyCircuitInputs!.newSubsidySalt as BigNumberish), - }, - }; - - // store it - fs.writeFileSync(subsidyFile, JSON.stringify(subsidyFileData, null, 4)); - logYellow(quiet, info(`Subsidy file:\n${JSON.stringify(subsidyFileData, null, 4)}\n`)); - - const susbsidyEndTime = Date.now(); - - logYellow(quiet, info(`gen subsidy proof took ${(susbsidyEndTime - subsidyStartTime) / 1000} seconds\n`)); - } - // tallying proofs logYellow(quiet, info(`Generating proofs of vote tallying...`)); const tallyStartTime = Date.now(); diff --git a/cli/ts/commands/proveOnChain.ts b/cli/ts/commands/proveOnChain.ts index 56b3327c30..6d9f1d7363 100644 --- a/cli/ts/commands/proveOnChain.ts +++ b/cli/ts/commands/proveOnChain.ts @@ -3,7 +3,6 @@ import { type BigNumberish } from "ethers"; import { MACI__factory as MACIFactory, AccQueue__factory as AccQueueFactory, - Subsidy__factory as SubsidyFactory, Tally__factory as TallyFactory, MessageProcessor__factory as MessageProcessorFactory, Poll__factory as PollFactory, @@ -11,7 +10,6 @@ import { Verifier__factory as VerifierFactory, formatProofForVerifierContract, type IVerifyingKeyStruct, - type Subsidy, } from "maci-contracts"; import { STATE_TREE_ARITY } from "maci-core"; import { G1Point, G2Point, hashLeftRight } from "maci-crypto"; @@ -43,11 +41,9 @@ import { export const proveOnChain = async ({ pollId, proofDir, - subsidyEnabled, maciAddress, messageProcessorAddress, tallyAddress, - subsidyAddress, signer, quiet = true, }: ProveOnChainArgs): Promise => { @@ -64,9 +60,6 @@ export const proveOnChain = async ({ if (!readContractAddress(`Tally-${pollId}`, network?.name) && !tallyAddress) { logError("Tally contract address is empty"); } - if (subsidyEnabled && !readContractAddress(`Subsidy-${pollId}`, network?.name) && !subsidyAddress) { - logError("Subsidy contract address is empty"); - } // check validity of contract addresses const maciContractAddress = maciAddress || readContractAddress("MACI", network?.name); @@ -74,11 +67,6 @@ export const proveOnChain = async ({ messageProcessorAddress || readContractAddress(`MessageProcessor-${pollId}`, network?.name); const tallyContractAddress = tallyAddress || readContractAddress(`Tally-${pollId}`, network?.name); - let subsidyContractAddress; - if (subsidyEnabled) { - subsidyContractAddress = subsidyAddress || readContractAddress(`Subsidy-${pollId}`, network?.name); - } - // check contracts are deployed on chain if (!(await contractExists(signer.provider!, maciContractAddress))) { logError("MACI contract does not exist"); @@ -92,10 +80,6 @@ export const proveOnChain = async ({ logError("Tally contract does not exist"); } - if (subsidyEnabled && subsidyContractAddress && !(await contractExists(signer.provider!, subsidyContractAddress))) { - logError("Subsidy contract does not exist"); - } - const maciContract = MACIFactory.connect(maciContractAddress, signer); const pollAddr = await maciContract.polls(pollId); @@ -108,11 +92,6 @@ export const proveOnChain = async ({ const mpContract = MessageProcessorFactory.connect(messageProcessorContractAddress, signer); const tallyContract = TallyFactory.connect(tallyContractAddress, signer); - let subsidyContract: Subsidy | undefined; - if (subsidyEnabled && subsidyContractAddress) { - subsidyContract = SubsidyFactory.connect(subsidyContractAddress, signer); - } - const messageAqContractAddress = (await pollContract.extContracts()).messageAq; if (!(await contractExists(signer.provider!, messageAqContractAddress))) { @@ -138,7 +117,6 @@ export const proveOnChain = async ({ const data = { processProofs: [] as Proof[], tallyProofs: [] as Proof[], - subsidyProofs: [] as Proof[], }; let numProcessProofs = 0; @@ -159,14 +137,6 @@ export const proveOnChain = async ({ match = filename.match(/tally_(\d+)/); if (match) { data.tallyProofs[Number(match[1])] = JSON.parse(fs.readFileSync(filepath).toString()) as Proof; - return; - } - - if (subsidyEnabled) { - match = filename.match(/subsidy_(\d+)/); - if (match) { - data.subsidyProofs[Number(match[1])] = JSON.parse(fs.readFileSync(filepath).toString()) as Proof; - } } }); @@ -177,7 +147,6 @@ export const proveOnChain = async ({ const numMessages = Number(numSignUpsAndMessages[1]); const messageBatchSize = STATE_TREE_ARITY ** Number(treeDepths.messageTreeSubDepth); const tallyBatchSize = STATE_TREE_ARITY ** Number(treeDepths.intStateTreeDepth); - const subsidyBatchSize = STATE_TREE_ARITY ** Number(treeDepths.intStateTreeDepth); let totalMessageBatches = numMessages <= messageBatchSize ? 1 : Math.floor(numMessages / messageBatchSize); if (numMessages > messageBatchSize && numMessages % messageBatchSize > 0) { @@ -346,92 +315,6 @@ export const proveOnChain = async ({ logGreen(quiet, success("All message processing proofs have been submitted.")); } - // subsidy calculations if any subsidy proofs are provided - if (subsidyEnabled && subsidyContractAddress && Object.keys(data.subsidyProofs).length !== 0) { - let rbi = Number(await subsidyContract!.rbi()); - let cbi = Number(await subsidyContract!.cbi()); - const num1DBatches = Math.ceil(numSignUps / subsidyBatchSize); - let subsidyBatchNum = rbi * num1DBatches + cbi; - const totalBatchNum = (num1DBatches * (num1DBatches + 1)) / 2; - - logYellow(quiet, info(`number of subsidy batch processed: ${subsidyBatchNum}, numleaf=${numSignUps}`)); - - // process all batches - for (let i = subsidyBatchNum; i < totalBatchNum; i += 1) { - if (i === 0) { - await subsidyContract!.updateSbCommitment().then((tx) => tx.wait()); - } - - const { proof, circuitInputs, publicInputs } = data.subsidyProofs[i]; - - // ensure the commitment matches - - const subsidyCommitmentOnChain = await subsidyContract!.subsidyCommitment(); - - if (subsidyCommitmentOnChain.toString() !== circuitInputs.currentSubsidyCommitment) { - logError(`subsidycommitment mismatch`); - } - - const packedValsOnChain = BigInt(await subsidyContract!.genSubsidyPackedVals(numSignUps)); - - if (circuitInputs.packedVals !== packedValsOnChain.toString()) { - logError("subsidy packedVals mismatch."); - } - // ensure the state and ballot root commitment matches - - const currentSbCommitmentOnChain = await subsidyContract!.sbCommitment(); - - if (currentSbCommitmentOnChain.toString() !== circuitInputs.sbCommitment) { - logError("currentSbCommitment mismatch."); - } - - const publicInputHashOnChain = await subsidyContract!.genSubsidyPublicInputHash( - numSignUps, - circuitInputs.newSubsidyCommitment as BigNumberish, - ); - - if (publicInputHashOnChain.toString() !== publicInputs[0]) { - logError("public input mismatch."); - } - - // format the proof so it can be verify on chain - const formattedProof = formatProofForVerifierContract(proof); - - try { - // verify the proof on chain and set the new subsidy commitment - - const tx = await subsidyContract!.updateSubsidy( - circuitInputs.newSubsidyCommitment as BigNumberish, - formattedProof, - ); - - const receipt = await tx.wait(); - - if (receipt?.status !== 1) { - logError("updateSubsidy() failed."); - } - - logYellow(quiet, info(`Transaction hash: ${receipt!.hash}`)); - logYellow(quiet, info(`Progress: ${subsidyBatchNum + 1} / ${totalBatchNum}`)); - - const [nrbi, ncbi] = await Promise.all([ - subsidyContract!.rbi().then(Number), - subsidyContract!.cbi().then(Number), - ]); - - rbi = nrbi; - cbi = ncbi; - subsidyBatchNum = rbi * num1DBatches + cbi; - } catch (err) { - logError((err as Error).message); - } - } - - if (subsidyBatchNum === totalBatchNum) { - logGreen(quiet, success("All subsidy calculation proofs have been submitted.")); - } - } - // vote tallying proofs const totalTallyBatches = numSignUps % tallyBatchSize === 0 diff --git a/cli/ts/commands/setVerifyingKeys.ts b/cli/ts/commands/setVerifyingKeys.ts index 93321b3e78..5eb57e2fb5 100644 --- a/cli/ts/commands/setVerifyingKeys.ts +++ b/cli/ts/commands/setVerifyingKeys.ts @@ -1,6 +1,6 @@ import { extractVk } from "maci-circuits"; import { type IVerifyingKeyStruct, VkRegistry__factory as VkRegistryFactory } from "maci-contracts"; -import { genProcessVkSig, genSubsidyVkSig, genTallyVkSig } from "maci-core"; +import { genProcessVkSig, genTallyVkSig } from "maci-core"; import { VerifyingKey } from "maci-domainobjs"; import fs from "fs"; @@ -32,7 +32,6 @@ export const setVerifyingKeys = async ({ processMessagesZkeyPath, tallyVotesZkeyPath, vkRegistry, - subsidyZkeyPath, signer, quiet = true, }: SetVerifyingKeysArgs): Promise => { @@ -56,10 +55,6 @@ export const setVerifyingKeys = async ({ logError(`${tallyVotesZkeyPath} does not exist.`); } - if (subsidyZkeyPath && !fs.existsSync(subsidyZkeyPath)) { - logError(`${subsidyZkeyPath} does not exist.`); - } - // extract the vks const processVk = VerifyingKey.fromObj(await extractVk(processMessagesZkeyPath)); const tallyVk = VerifyingKey.fromObj(await extractVk(tallyVotesZkeyPath)); @@ -139,34 +134,6 @@ export const setVerifyingKeys = async ({ logError("This tally verifying key is already set in the contract"); } - // do the same for the subsidy vk if any - if (subsidyZkeyPath) { - const ssMatch = subsidyZkeyPath.match(/.+_(\d+)-(\d+)-(\d+)/); - - if (!ssMatch) { - logError(`${subsidyZkeyPath} has an invalid filename`); - return; - } - - const ssStateTreeDepth = Number(ssMatch[1]); - const ssIntStateTreeDepth = Number(ssMatch[2]); - const ssVoteOptionTreeDepth = Number(ssMatch[3]); - - if ( - stateTreeDepth !== ssStateTreeDepth || - intStateTreeDepth !== ssIntStateTreeDepth || - voteOptionTreeDepth !== ssVoteOptionTreeDepth - ) { - logError("Incorrect .zkey file; please check the circuit params"); - } - - const subsidyVkSig = genSubsidyVkSig(stateTreeDepth, intStateTreeDepth, voteOptionTreeDepth); - - if (await vkRegistryContract.isSubsidyVkSet(subsidyVkSig)) { - info("This subsidy verifying key is already set in the contract"); - } - } - // actually set those values try { logYellow(quiet, info("Setting verifying keys...")); @@ -206,35 +173,6 @@ export const setVerifyingKeys = async ({ if (!compareVks(tallyVk, tallyVkOnChain)) { logError("tallyVk mismatch"); } - - // set subsidy keys if any - if (subsidyZkeyPath) { - const subsidyVk = VerifyingKey.fromObj(await extractVk(subsidyZkeyPath)); - - const txReceipt = await vkRegistryContract - .setSubsidyKeys( - stateTreeDepth, - intStateTreeDepth, - voteOptionTreeDepth, - subsidyVk.asContractParam() as IVerifyingKeyStruct, - ) - .then((transaction) => transaction.wait(2)); - - if (txReceipt?.status !== 1) { - logError("Set subsidy keys transaction failed"); - } - - logYellow(quiet, info(`Transaction hash: ${tx.hash}`)); - - const subsidyVkOnChain = await vkRegistryContract.getSubsidyVk( - stateTreeDepth, - intStateTreeDepth, - voteOptionTreeDepth, - ); - if (!compareVks(subsidyVk, subsidyVkOnChain)) { - logError("subsidyVk mismatch"); - } - } } catch (error) { logError((error as Error).message); } diff --git a/cli/ts/commands/verify.ts b/cli/ts/commands/verify.ts index 8251074756..100246096b 100644 --- a/cli/ts/commands/verify.ts +++ b/cli/ts/commands/verify.ts @@ -2,7 +2,6 @@ import { Tally__factory as TallyFactory, TallyNonQv__factory as TallyNonQvFactory, MACI__factory as MACIFactory, - Subsidy__factory as SubsidyFactory, Poll__factory as PollFactory, Tally, TallyNonQv, @@ -17,17 +16,14 @@ import { info, logError, logGreen, logYellow, success } from "../utils/theme"; import { verifyPerVOSpentVoiceCredits, verifyTallyResults } from "../utils/verifiers"; /** - * Verify the results of a poll and optionally the subsidy results on-chain + * Verify the results of a poll on-chain * @param VerifyArgs - The arguments for the verify command */ export const verify = async ({ pollId, - subsidyEnabled, tallyData, maciAddress, tallyAddress, - subsidyAddress, - subsidyData, signer, quiet = true, }: VerifyArgs): Promise => { @@ -59,28 +55,12 @@ export const verify = async ({ logError(`Error: there is no MACI contract deployed at ${maciContractAddress}.`); } - let subsidyContractAddress = ""; - - // subsidy validation - if (subsidyEnabled) { - subsidyContractAddress = subsidyAddress!; - - if (!subsidyContractAddress) { - logError("Subsidy contract address is empty"); - } - - if (!(await contractExists(signer.provider!, subsidyContractAddress))) { - logError(`Error: there is no Subsidy contract deployed at ${subsidyContractAddress}.`); - } - } - // get the contract objects const maciContract = MACIFactory.connect(maciContractAddress, signer); const pollAddr = await maciContract.polls(pollId); const pollContract = PollFactory.connect(pollAddr, signer); - const subsidyContract = subsidyEnabled ? SubsidyFactory.connect(subsidyContractAddress, signer) : undefined; const tallyContract = useQv ? TallyFactory.connect(tallyContractAddress, signer) : TallyNonQvFactory.connect(tallyContractAddress, signer); @@ -237,35 +217,4 @@ export const verify = async ({ ); } } - - // verify subsidy result if subsidy file is provided - if (subsidyEnabled && subsidyData && subsidyContract !== undefined) { - const onChainSubsidyCommitment = BigInt(await subsidyContract.subsidyCommitment()); - - logYellow(quiet, info(`on-chain subsidy commitment: ${onChainSubsidyCommitment.toString(16)}`)); - - // check the results commitment - const validResultsSubsidyCommitment = subsidyData.newSubsidyCommitment.match(/0x[a-fA-F0-9]+/); - - if (!validResultsSubsidyCommitment) { - logError("Invalid results commitment format"); - } - - if (subsidyData.results.subsidy.length !== numVoteOptions) { - logError("Wrong number of vote options."); - } - - // compute the new SubsidyCommitment - const newSubsidyCommitment = genTreeCommitment( - subsidyData.results.subsidy.map((x) => BigInt(x)), - BigInt(subsidyData.results.salt), - voteOptionTreeDepth, - ); - - if (onChainSubsidyCommitment !== newSubsidyCommitment) { - logError("The on-chain subsidy commitment does not match."); - } - - logGreen(quiet, success("The on-chain subsidy commitment matches.")); - } }; diff --git a/cli/ts/index.ts b/cli/ts/index.ts index 46429419f1..13c97abed5 100644 --- a/cli/ts/index.ts +++ b/cli/ts/index.ts @@ -32,7 +32,7 @@ import { checkVerifyingKeys, genLocalState, } from "./commands"; -import { SubsidyData, TallyData, logError, promptSensitiveValue, readContractAddress } from "./utils"; +import { TallyData, logError, promptSensitiveValue, readContractAddress } from "./utils"; // set the description version and name of the cli tool const { description, version, name } = JSON.parse( @@ -101,10 +101,6 @@ program "-t, --tally-votes-zkey ", "the tally votes zkey path (see different options for zkey files to use specific circuits https://maci.pse.dev/docs/trusted-setup, https://maci.pse.dev/docs/testing/#pre-compiled-artifacts-for-testing)", ) - .option( - "-ss, --subsidy-zkey ", - "the subsidy zkey path (see different options for zkey files to use specific circuits https://maci.pse.dev/docs/trusted-setup, https://maci.pse.dev/docs/testing/#pre-compiled-artifacts-for-testing)", - ) .action(async (cmdOptions) => { try { const signer = await getSigner(); @@ -118,7 +114,6 @@ program processMessagesZkeyPath: cmdOptions.processMessagesZkey, tallyVotesZkeyPath: cmdOptions.tallyVotesZkey, vkRegistry: cmdOptions.vkContract, - subsidyZkeyPath: cmdOptions.subsidyZkey, quiet: cmdOptions.quiet, signer, }); @@ -205,12 +200,6 @@ program .requiredOption("-m, --msg-tree-depth ", "the message tree depth", parseInt) .requiredOption("-v, --vote-option-tree-depth ", "the vote option tree depth", parseInt) .requiredOption("-pk, --pubkey ", "the coordinator public key") - .requiredOption( - "-se, --subsidy-enabled ", - "whether to deploy subsidy contract", - (value) => value === "true", - false, - ) .option("-x, --maci-address ", "the MACI contract address") .option("-q, --quiet ", "whether to print values to the console", (value) => value === "true", false) .option("-r, --rpc-provider ", "the rpc provider URL") @@ -225,7 +214,6 @@ program messageTreeDepth: cmdObj.msgTreeDepth, voteOptionTreeDepth: cmdObj.voteOptionTreeDepth, coordinatorPubkey: cmdObj.pubkey, - subsidyEnabled: cmdObj.subsidyEnabled, maciAddress: cmdObj.maciAddress, vkRegistryAddress: cmdObj.vkRegistryAddress, quiet: cmdObj.quiet, @@ -254,10 +242,6 @@ program .option("-k, --vk-registry ", "the vk registry contract address") .option("-q, --quiet ", "whether to print values to the console", (value) => value === "true", false) .option("-r, --rpc-provider ", "the rpc provider URL") - .option( - "-ss, --subsidy-zkey ", - "the subsidy zkey path (see different options for zkey files to use specific circuits https://maci.pse.dev/docs/trusted-setup, https://maci.pse.dev/docs/testing/#pre-compiled-artifacts-for-testing)", - ) .action(async (cmdObj) => { try { const signer = await getSigner(); @@ -271,7 +255,6 @@ program processMessagesZkeyPath: cmdObj.processMessagesZkey, tallyVotesZkeyPath: cmdObj.tallyVotesZkey, vkRegistry: cmdObj.vkRegistry, - subsidyZkeyPath: cmdObj.subsidyZkey, quiet: cmdObj.quiet, signer, }); @@ -499,22 +482,14 @@ program }); program .command("verify") - .description("verify the results of a poll and optionally the subsidy results") + .description("verify the results of a poll") .requiredOption("-o, --poll-id ", "the poll id", BigInt) .requiredOption( "-t, --tally-file ", "the tally file with results, per vote option spent credits, spent voice credits total", ) - .requiredOption( - "-se, --subsidy-enabled ", - "whether to deploy subsidy contract", - (value) => value === "true", - false, - ) - .option("-s, --subsidy-file ", "the subsidy file") .option("-x, --maci-address ", "the MACI contract address") .option("-tc, --tally-contract ", "the tally contract address") - .option("-sc, --subsidy-contract ", "the subsidy contract address") .option("-q, --quiet ", "whether to print values to the console", (value) => value === "true", false) .option("-r, --rpc-provider ", "the rpc provider URL") .action(async (cmdObj) => { @@ -530,27 +505,14 @@ program const tallyData = JSON.parse(fs.readFileSync(cmdObj.tallyFile, { encoding: "utf8" })) as TallyData; const maciAddress = tallyData.maci || cmdObj.maciAddress || readContractAddress("MACI", network?.name); - const subsidyAddress = cmdObj.subsidyContract || readContractAddress(`Subsidy-${cmdObj.pollId}`, network?.name); const tallyAddress = tallyData.tallyAddress || cmdObj.tallyContract || readContractAddress(`Tally-${cmdObj.pollId}`, network?.name); - // read the subsidy file - if (cmdObj.subsidyEnabled && (!cmdObj.subsidyFile || !fs.existsSync(cmdObj.subsidyFile))) { - logError(`There is no such file: ${cmdObj.subsidyFile}`); - } - - const subsidyData = cmdObj.subsidyEnabled - ? (JSON.parse(fs.readFileSync(cmdObj.subsidyFile!, { encoding: "utf8" })) as SubsidyData) - : undefined; - await verify({ tallyData, pollId: cmdObj.pollId, - subsidyEnabled: cmdObj.subsidyEnabled, maciAddress, tallyAddress, - subsidyAddress, - subsidyData, quiet: cmdObj.quiet, signer, }); @@ -569,17 +531,13 @@ program "the tally file with results, per vote option spent credits, spent voice credits total", ) .option("-ta, --tally-address ", "the tally contract address") - .option("-s, --subsidy-file ", "the subsidy file") .option("-r, --rapidsnark ", "the path to the rapidsnark binary") .option("-wp, --process-witnessgen ", "the path to the process witness generation binary") .option("-pd, --process-witnessdat ", "the path to the process witness dat file") .option("-wt, --tally-witnessgen ", "the path to the tally witness generation binary") .option("-td, --tally-witnessdat ", "the path to the tally witness dat file") - .option("-ws, --subsidy-witnessgen ", "the path to the subsidy witness generation binary") - .option("-sd, --subsidy-witnessdat ", "the path to the subsidy witness dat file") .requiredOption("-zp, --process-zkey ", "the path to the process zkey") .requiredOption("-zt, --tally-zkey ", "the path to the tally zkey") - .option("-zs, --subsidy-zkey ", "the path to the subsidy zkey") .option("-q, --quiet ", "whether to print values to the console", (value) => value === "true", false) .option("-p, --rpc-provider ", "the rpc provider URL") .requiredOption("-f, --output ", "the output directory for proofs") @@ -587,7 +545,6 @@ program .option("-w, --wasm", "whether to use the wasm binaries") .option("-pw, --process-wasm ", "the path to the process witness generation wasm binary") .option("-tw, --tally-wasm ", "the path to the tally witness generation wasm binary") - .option("-sw, --subsidy-wasm ", "the path to the subsidy witness generation wasm binary") .option("-st, --state-file ", "the path to the state file containing the serialized maci state") .option("-sb, --start-block ", "the block number to start looking for events from", parseInt) .option("-eb, --end-block ", "the block number to end looking for events from", parseInt) @@ -603,21 +560,16 @@ program tallyZkey: cmdObj.tallyZkey, processZkey: cmdObj.processZkey, pollId: cmdObj.pollId, - subsidyFile: cmdObj.subsidyFile, - subsidyZkey: cmdObj.subsidyZkey, rapidsnark: cmdObj.rapidsnark, processWitgen: cmdObj.processWitnessgen, processDatFile: cmdObj.processWitnessdat, tallyWitgen: cmdObj.tallyWitnessgen, tallyDatFile: cmdObj.tallyWitnessdat, - subsidyWitgen: cmdObj.subsidyWitnessgen, - subsidyDatFile: cmdObj.subsidyWitnessdat, coordinatorPrivKey: cmdObj.privkey, maciAddress: cmdObj.maciAddress, transactionHash: cmdObj.transactionHash, processWasm: cmdObj.processWasm, tallyWasm: cmdObj.tallyWasm, - subsidyWasm: cmdObj.subsidyWasm, useWasm: cmdObj.wasm, stateFile: cmdObj.stateFile, startBlock: cmdObj.startBlock, @@ -672,18 +624,11 @@ program .command("proveOnChain") .description("prove the results of a poll on chain") .requiredOption("-o, --poll-id ", "the poll id", BigInt) - .requiredOption( - "-se, --subsidy-enabled ", - "whether to deploy subsidy contract", - (value) => value === "true", - false, - ) .option("-q, --quiet ", "whether to print values to the console", (value) => value === "true", false) .option("-r, --rpc-provider ", "the rpc provider URL") .option("-x, --maci-address ", "the MACI contract address") .option("-p, --message-processor-address ", "the message processor contract address") .option("-t, --tally-contract ", "the tally contract address") - .option("-s, --subsidy-contract ", "the subsidy contract address") .requiredOption("-f, --proof-dir ", "the proof output directory from the genProofs subcommand") .action(async (cmdObj) => { try { @@ -692,11 +637,9 @@ program await proveOnChain({ pollId: cmdObj.pollId, proofDir: cmdObj.proofDir, - subsidyEnabled: cmdObj.subsidyEnabled, maciAddress: cmdObj.maciAddress, messageProcessorAddress: cmdObj.messageProcessorAddress, tallyAddress: cmdObj.tallyContract, - subsidyAddress: cmdObj.subsidyContract, quiet: cmdObj.quiet, signer, }); @@ -751,7 +694,6 @@ export type { VerifyArgs, ProveOnChainArgs, DeployArgs, - SubsidyData, IRegisteredUserArgs, IGenKeypairArgs, IGetPollArgs, diff --git a/cli/ts/sdk/index.ts b/cli/ts/sdk/index.ts index 20166b677f..a54f7d749e 100644 --- a/cli/ts/sdk/index.ts +++ b/cli/ts/sdk/index.ts @@ -11,7 +11,6 @@ export type { Signer } from "ethers"; export type { TallyData, - SubsidyData, PublishArgs, SignupArgs, ISignupData, diff --git a/cli/ts/utils/index.ts b/cli/ts/utils/index.ts index 082cf5a505..49f6aedae6 100644 --- a/cli/ts/utils/index.ts +++ b/cli/ts/utils/index.ts @@ -38,7 +38,6 @@ export type { TallyData, TopupArgs, VerifyArgs, - SubsidyData, IRegisteredUserArgs, IGenKeypairArgs, IGetPollArgs, diff --git a/cli/ts/utils/interfaces.ts b/cli/ts/utils/interfaces.ts index 9067276793..181b298efe 100644 --- a/cli/ts/utils/interfaces.ts +++ b/cli/ts/utils/interfaces.ts @@ -22,7 +22,6 @@ export interface PollContracts { poll: string; messageProcessor: string; tally: string; - subsidy?: string; } /** @@ -126,20 +125,6 @@ export interface TallyData { }; } -/** - * A util interface that represents a subsidy file - */ -export interface SubsidyData { - provider: string; - maci: string; - pollId: bigint; - newSubsidyCommitment: string; - results: { - subsidy: string[]; - salt: string; - }; -} - /** * Proof interface for cli commands */ @@ -248,11 +233,6 @@ export interface CheckVerifyingKeysArgs { */ vkRegistry?: string; - /** - * The path to the subsidy zkey - */ - subsidyZkeyPath?: string; - /** * Whether to log the output */ @@ -353,11 +333,6 @@ export interface DeployPollArgs { */ coordinatorPubkey: string; - /** - * Whether to deploy subsidy contract - */ - subsidyEnabled: boolean; - /** * A signer object */ @@ -479,16 +454,6 @@ export interface GenProofsArgs { */ signer: Signer; - /** - * The file to store the subsidy proof - */ - subsidyFile?: string; - - /** - * The path to the subsidy zkey file - */ - subsidyZkey?: string; - /** * The path to the rapidsnark binary */ @@ -514,16 +479,6 @@ export interface GenProofsArgs { */ tallyDatFile?: string; - /** - * The path to the subsidy witnessgen binary - */ - subsidyWitgen?: string; - - /** - * The path to the subsidy dat file - */ - subsidyDatFile?: string; - /** * The coordinator's private key */ @@ -549,11 +504,6 @@ export interface GenProofsArgs { */ tallyWasm?: string; - /** - * The path to the subsidy wasm file - */ - subsidyWasm?: string; - /** * Whether to use wasm or rapidsnark */ @@ -669,11 +619,6 @@ export interface ProveOnChainArgs { */ proofDir: string; - /** - * Whether to deploy subsidy contract - */ - subsidyEnabled: boolean; - /** * A signer object */ @@ -694,11 +639,6 @@ export interface ProveOnChainArgs { */ tallyAddress?: string; - /** - * The address of the Subsidy contract - */ - subsidyAddress?: string; - /** * Whether to log the output */ @@ -879,11 +819,6 @@ export interface SetVerifyingKeysArgs { */ vkRegistry?: string; - /** - * The path to the subsidy zkey - */ - subsidyZkeyPath?: string; - /** * Whether to log the output */ @@ -1079,11 +1014,6 @@ export interface VerifyArgs { */ pollId: bigint; - /** - * Whether to deploy subsidy contract - */ - subsidyEnabled: boolean; - /** * A signer object */ @@ -1104,16 +1034,6 @@ export interface VerifyArgs { */ tallyAddress: string; - /** - * The address of the Subsidy contract - */ - subsidyAddress?: string; - - /** - * The subsidy data - */ - subsidyData?: SubsidyData; - /** * Whether to log the output */ diff --git a/contracts/contracts/MACI.sol b/contracts/contracts/MACI.sol index 0ad24318eb..7f5578b5ab 100644 --- a/contracts/contracts/MACI.sol +++ b/contracts/contracts/MACI.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.10; import { IPollFactory } from "./interfaces/IPollFactory.sol"; import { IMessageProcessorFactory } from "./interfaces/IMPFactory.sol"; -import { ITallySubsidyFactory } from "./interfaces/ITallySubsidyFactory.sol"; +import { ITallyFactory } from "./interfaces/ITallyFactory.sol"; import { InitialVoiceCreditProxy } from "./initialVoiceCreditProxy/InitialVoiceCreditProxy.sol"; import { SignUpGatekeeper } from "./gatekeepers/SignUpGatekeeper.sol"; import { AccQueue } from "./trees/AccQueue.sol"; @@ -54,10 +54,7 @@ contract MACI is IMACI, Params, Utilities, Ownable { IMessageProcessorFactory public immutable messageProcessorFactory; /// @notice Factory contract that deploy a Tally contract - ITallySubsidyFactory public immutable tallyFactory; - - /// @notice Factory contract that deploy a Subsidy contract - ITallySubsidyFactory public immutable subsidyFactory; + ITallyFactory public immutable tallyFactory; /// @notice The state AccQueue. Represents a mapping between each user's public key /// and their voice credit balance. @@ -76,7 +73,6 @@ contract MACI is IMACI, Params, Utilities, Ownable { address poll; address messageProcessor; address tally; - address subsidy; } // Events @@ -113,7 +109,6 @@ contract MACI is IMACI, Params, Utilities, Ownable { /// @param _pollFactory The PollFactory contract /// @param _messageProcessorFactory The MessageProcessorFactory contract /// @param _tallyFactory The TallyFactory contract - /// @param _subsidyFactory The SubsidyFactory contract /// @param _signUpGatekeeper The SignUpGatekeeper contract /// @param _initialVoiceCreditProxy The InitialVoiceCreditProxy contract /// @param _topupCredit The TopupCredit contract @@ -121,8 +116,7 @@ contract MACI is IMACI, Params, Utilities, Ownable { constructor( IPollFactory _pollFactory, IMessageProcessorFactory _messageProcessorFactory, - ITallySubsidyFactory _tallyFactory, - ITallySubsidyFactory _subsidyFactory, + ITallyFactory _tallyFactory, SignUpGatekeeper _signUpGatekeeper, InitialVoiceCreditProxy _initialVoiceCreditProxy, TopupCredit _topupCredit, @@ -141,7 +135,6 @@ contract MACI is IMACI, Params, Utilities, Ownable { pollFactory = _pollFactory; messageProcessorFactory = _messageProcessorFactory; tallyFactory = _tallyFactory; - subsidyFactory = _subsidyFactory; topupCredit = _topupCredit; signUpGatekeeper = _signUpGatekeeper; initialVoiceCreditProxy = _initialVoiceCreditProxy; @@ -206,15 +199,13 @@ 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 useSubsidy If true, the Poll will use the Subsidy contract /// @return pollAddr a new Poll contract address function deployPoll( uint256 _duration, TreeDepths memory _treeDepths, PubKey memory _coordinatorPubKey, address _verifier, - address _vkRegistry, - bool useSubsidy + address _vkRegistry ) public virtual onlyOwner returns (PollContracts memory pollAddr) { // cache the poll to a local variable so we can increment it uint256 pollId = nextPollId; @@ -249,15 +240,10 @@ 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 subsidy; - if (useSubsidy) { - subsidy = subsidyFactory.deploy(_verifier, _vkRegistry, p, mp, _owner); - } - polls[pollId] = p; // store the addresses in a struct so they can be returned - pollAddr = PollContracts({ poll: p, messageProcessor: mp, tally: tally, subsidy: subsidy }); + pollAddr = PollContracts({ poll: p, messageProcessor: mp, tally: tally }); emit DeployPoll(pollId, _coordinatorPubKey.x, _coordinatorPubKey.y, pollAddr); } diff --git a/contracts/contracts/Subsidy.sol b/contracts/contracts/Subsidy.sol deleted file mode 100644 index 7a68ad1785..0000000000 --- a/contracts/contracts/Subsidy.sol +++ /dev/null @@ -1,160 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.10; - -import { IMACI } from "./interfaces/IMACI.sol"; -import { IMessageProcessor } from "./interfaces/IMessageProcessor.sol"; -import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; -import { IPoll } from "./interfaces/IPoll.sol"; -import { SnarkCommon } from "./crypto/SnarkCommon.sol"; -import { Hasher } from "./crypto/Hasher.sol"; -import { CommonUtilities } from "./utilities/CommonUtilities.sol"; -import { IVerifier } from "./interfaces/IVerifier.sol"; -import { IVkRegistry } from "./interfaces/IVkRegistry.sol"; - -/// @title Subsidy -/// @notice This contract is used to verify that the subsidy calculations -/// are correct. It is also used to update the subsidy commitment if the -/// proof is valid. -contract Subsidy is Ownable, CommonUtilities, Hasher, SnarkCommon { - // row batch index - uint256 public rbi; - // column batch index - uint256 public cbi; - - // The final commitment to the state and ballot roots - uint256 public sbCommitment; - uint256 public subsidyCommitment; - - uint256 private constant TREE_ARITY = 5; - - IVerifier public immutable verifier; - IVkRegistry public immutable vkRegistry; - IPoll public immutable poll; - IMessageProcessor public immutable mp; - - // Custom errors - error ProcessingNotComplete(); - error InvalidSubsidyProof(); - error AllSubsidyCalculated(); - error VkNotSet(); - error NumSignUpsTooLarge(); - error RbiTooLarge(); - error CbiTooLarge(); - - /// @notice Create a new Subsidy contract - /// @param _verifier The Verifier contract - /// @param _vkRegistry The VkRegistry contract - /// @param _poll The Poll contract - /// @param _mp The MessageProcessor contract - constructor(address _verifier, address _vkRegistry, address _poll, address _mp) payable { - verifier = IVerifier(_verifier); - vkRegistry = IVkRegistry(_vkRegistry); - poll = IPoll(_poll); - mp = IMessageProcessor(_mp); - } - - /// @notice Update the currentSbCommitment if the proof is valid. - /// @dev currentSbCommitment is the commitment to the state and ballot roots - function updateSbCommitment() public onlyOwner { - // Require that all messages have been processed - if (!mp.processingComplete()) { - revert ProcessingNotComplete(); - } - - // only update it once - if (sbCommitment == 0) { - sbCommitment = mp.sbCommitment(); - } - } - - /// @notice Generate the packed values for the subsidy proof - /// @param _numSignUps The number of signups - /// @return result The packed values - function genSubsidyPackedVals(uint256 _numSignUps) public view returns (uint256 result) { - if (_numSignUps >= 2 ** 50) revert NumSignUpsTooLarge(); - if (rbi >= 2 ** 50) revert RbiTooLarge(); - if (cbi >= 2 ** 50) revert CbiTooLarge(); - result = (_numSignUps << 100) + (rbi << 50) + cbi; - } - - /// @notice Generate the public input hash for the subsidy proof - /// @param _numSignUps The number of signups - /// @param _newSubsidyCommitment The new subsidy commitment - /// @return inputHash The public input hash - function genSubsidyPublicInputHash( - uint256 _numSignUps, - uint256 _newSubsidyCommitment - ) public view returns (uint256 inputHash) { - uint256 packedVals = genSubsidyPackedVals(_numSignUps); - uint256[] memory input = new uint256[](4); - input[0] = packedVals; - input[1] = sbCommitment; - input[2] = subsidyCommitment; - input[3] = _newSubsidyCommitment; - inputHash = sha256Hash(input); - } - - /// @notice Update the subsidy commitment if the proof is valid - /// @param _newSubsidyCommitment The new subsidy commitment - /// @param _proof The proof - function updateSubsidy(uint256 _newSubsidyCommitment, uint256[8] calldata _proof) external onlyOwner { - _votingPeriodOver(poll); - updateSbCommitment(); - - (uint8 intStateTreeDepth, , , ) = poll.treeDepths(); - - uint256 subsidyBatchSize = TREE_ARITY ** intStateTreeDepth; - - (uint256 numSignUps, ) = poll.numSignUpsAndMessages(); - - // Require that there are unfinished ballots left - if (rbi * subsidyBatchSize > numSignUps) { - revert AllSubsidyCalculated(); - } - - bool isValid = verifySubsidyProof(_proof, numSignUps, _newSubsidyCommitment); - if (!isValid) { - revert InvalidSubsidyProof(); - } - subsidyCommitment = _newSubsidyCommitment; - increaseSubsidyIndex(subsidyBatchSize, numSignUps); - } - - /// @notice Increase the subsidy batch index (rbi, cbi) to next, - /// it will try to cbi++ if the whole batch can fit into numLeaves - /// otherwise it will increase row index: rbi++. - /// Each batch for subsidy calculation is 2 dimensional: batchSize*batchSize - /// @param batchSize the size of 1 dimensional batch over the signup users - /// @param numLeaves total number of leaves in stateTree, i.e. number of signup users - function increaseSubsidyIndex(uint256 batchSize, uint256 numLeaves) internal { - if (cbi * batchSize + batchSize < numLeaves) { - cbi++; - } else { - rbi++; - cbi = rbi; - } - } - - /// @notice Verify the subsidy proof using the Groth16 on chain verifier - /// @param _proof The proof - /// @param _numSignUps The number of signups - /// @param _newSubsidyCommitment The new subsidy commitment - /// @return isValid True if the proof is valid - function verifySubsidyProof( - uint256[8] calldata _proof, - uint256 _numSignUps, - uint256 _newSubsidyCommitment - ) public view returns (bool isValid) { - (uint8 intStateTreeDepth, , , uint8 voteOptionTreeDepth) = poll.treeDepths(); - (IMACI maci, , ) = poll.extContracts(); - - // Get the verifying key - VerifyingKey memory vk = vkRegistry.getSubsidyVk(maci.stateTreeDepth(), intStateTreeDepth, voteOptionTreeDepth); - - // Get the public inputs - uint256 publicInputHash = genSubsidyPublicInputHash(_numSignUps, _newSubsidyCommitment); - - // Verify the proof - isValid = verifier.verify(_proof, vk, publicInputHash); - } -} diff --git a/contracts/contracts/SubsidyFactory.sol b/contracts/contracts/SubsidyFactory.sol deleted file mode 100644 index 0be338de52..0000000000 --- a/contracts/contracts/SubsidyFactory.sol +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.10; - -import { Subsidy } from "./Subsidy.sol"; -import { ITallySubsidyFactory } from "./interfaces/ITallySubsidyFactory.sol"; - -/// @title SubsidyFactory -/// @notice A factory contract which deploys Subsidy contracts. -contract SubsidyFactory is ITallySubsidyFactory { - /// @inheritdoc ITallySubsidyFactory - function deploy( - address _verifier, - address _vkRegistry, - address _poll, - address _messageProcessor, - address _owner - ) public returns (address subsidyAddr) { - /// @notice deploy Subsidy for this Poll - Subsidy subsidy = new Subsidy(_verifier, _vkRegistry, _poll, _messageProcessor); - subsidy.transferOwnership(_owner); - subsidyAddr = address(subsidy); - } -} diff --git a/contracts/contracts/TallyFactory.sol b/contracts/contracts/TallyFactory.sol index bbf0746928..18a71e2053 100644 --- a/contracts/contracts/TallyFactory.sol +++ b/contracts/contracts/TallyFactory.sol @@ -2,12 +2,12 @@ pragma solidity ^0.8.10; import { Tally } from "./Tally.sol"; -import { ITallySubsidyFactory } from "./interfaces/ITallySubsidyFactory.sol"; +import { ITallyFactory } from "./interfaces/ITallyFactory.sol"; /// @title TallyFactory /// @notice A factory contract which deploys Tally contracts. -contract TallyFactory is ITallySubsidyFactory { - /// @inheritdoc ITallySubsidyFactory +contract TallyFactory is ITallyFactory { + /// @inheritdoc ITallyFactory function deploy( address _verifier, address _vkRegistry, diff --git a/contracts/contracts/TallyNonQvFactory.sol b/contracts/contracts/TallyNonQvFactory.sol index 099fe14058..a07a3d118f 100644 --- a/contracts/contracts/TallyNonQvFactory.sol +++ b/contracts/contracts/TallyNonQvFactory.sol @@ -2,12 +2,12 @@ pragma solidity ^0.8.10; import { TallyNonQv } from "./TallyNonQv.sol"; -import { ITallySubsidyFactory } from "./interfaces/ITallySubsidyFactory.sol"; +import { ITallyFactory } from "./interfaces/ITallyFactory.sol"; /// @title TallyNonQvFactory /// @notice A factory contract which deploys TallyNonQv contracts. -contract TallyNonQvFactory is ITallySubsidyFactory { - /// @inheritdoc ITallySubsidyFactory +contract TallyNonQvFactory is ITallyFactory { + /// @inheritdoc ITallyFactory function deploy( address _verifier, address _vkRegistry, diff --git a/contracts/contracts/VkRegistry.sol b/contracts/contracts/VkRegistry.sol index a4a9a50a61..7a310c8e7f 100644 --- a/contracts/contracts/VkRegistry.sol +++ b/contracts/contracts/VkRegistry.sol @@ -16,16 +16,11 @@ contract VkRegistry is Ownable, SnarkCommon, IVkRegistry { mapping(uint256 => VerifyingKey) internal tallyVks; mapping(uint256 => bool) internal tallyVkSet; - mapping(uint256 => VerifyingKey) internal subsidyVks; - mapping(uint256 => bool) internal subsidyVkSet; - event ProcessVkSet(uint256 _sig); event TallyVkSet(uint256 _sig); - event SubsidyVkSet(uint256 _sig); error ProcessVkAlreadySet(); error TallyVkAlreadySet(); - error SubsidyVkAlreadySet(); error ProcessVkNotSet(); error TallyVkNotSet(); error SubsidyVkNotSet(); @@ -48,13 +43,6 @@ contract VkRegistry is Ownable, SnarkCommon, IVkRegistry { isSet = tallyVkSet[_sig]; } - /// @notice Check if the subsidy verifying key is set - /// @param _sig The signature - /// @return isSet whether the verifying key is set - function isSubsidyVkSet(uint256 _sig) public view returns (bool isSet) { - isSet = subsidyVkSet[_sig]; - } - /// @notice generate the signature for the process verifying key /// @param _stateTreeDepth The state tree depth /// @param _messageTreeDepth The message tree depth @@ -82,19 +70,6 @@ contract VkRegistry is Ownable, SnarkCommon, IVkRegistry { sig = (_stateTreeDepth << 128) + (_intStateTreeDepth << 64) + _voteOptionTreeDepth; } - /// @notice generate the signature for the subsidy verifying key - /// @param _stateTreeDepth The state tree depth - /// @param _intStateTreeDepth The intermediate state tree depth - /// @param _voteOptionTreeDepth The vote option tree depth - /// @return sig The signature - function genSubsidyVkSig( - uint256 _stateTreeDepth, - uint256 _intStateTreeDepth, - uint256 _voteOptionTreeDepth - ) public pure returns (uint256 sig) { - sig = (_stateTreeDepth << 128) + (_intStateTreeDepth << 64) + _voteOptionTreeDepth; - } - /// @notice Set the process and tally verifying keys for a certain combination /// of parameters /// @param _stateTreeDepth The state tree depth @@ -146,35 +121,6 @@ contract VkRegistry is Ownable, SnarkCommon, IVkRegistry { emit ProcessVkSet(processVkSig); } - /// @notice Set the process verifying key for a certain combination - /// of parameters - /// @param _stateTreeDepth The state tree depth - /// @param _intStateTreeDepth The intermediate state tree depth - /// @param _voteOptionTreeDepth The vote option tree depth - /// @param _subsidyVk The verifying key - function setSubsidyKeys( - uint256 _stateTreeDepth, - uint256 _intStateTreeDepth, - uint256 _voteOptionTreeDepth, - VerifyingKey calldata _subsidyVk - ) public onlyOwner { - uint256 subsidyVkSig = genSubsidyVkSig(_stateTreeDepth, _intStateTreeDepth, _voteOptionTreeDepth); - - if (subsidyVkSet[subsidyVkSig]) revert SubsidyVkAlreadySet(); - - VerifyingKey storage subsidyVk = subsidyVks[subsidyVkSig]; - subsidyVk.alpha1 = _subsidyVk.alpha1; - subsidyVk.beta2 = _subsidyVk.beta2; - subsidyVk.gamma2 = _subsidyVk.gamma2; - subsidyVk.delta2 = _subsidyVk.delta2; - for (uint8 i = 0; i < _subsidyVk.ic.length; i++) { - subsidyVk.ic.push(_subsidyVk.ic[i]); - } - subsidyVkSet[subsidyVkSig] = true; - - emit SubsidyVkSet(subsidyVkSig); - } - /// @notice Check if the process verifying key is set /// @param _stateTreeDepth The state tree depth /// @param _messageTreeDepth The message tree depth @@ -246,39 +192,4 @@ contract VkRegistry is Ownable, SnarkCommon, IVkRegistry { vk = getTallyVkBySig(sig); } - - /// @notice Check if the subsidy verifying key is set - /// @param _stateTreeDepth The state tree depth - /// @param _intStateTreeDepth The intermediate state tree depth - /// @param _voteOptionTreeDepth The vote option tree depth - /// @return isSet whether the verifying key is set - function hasSubsidyVk( - uint256 _stateTreeDepth, - uint256 _intStateTreeDepth, - uint256 _voteOptionTreeDepth - ) public view returns (bool isSet) { - uint256 sig = genSubsidyVkSig(_stateTreeDepth, _intStateTreeDepth, _voteOptionTreeDepth); - - isSet = subsidyVkSet[sig]; - } - - /// @notice Get the subsidy verifying key by signature - /// @param _sig The signature - /// @return vk The verifying key - function getSubsidyVkBySig(uint256 _sig) public view returns (VerifyingKey memory vk) { - if (!subsidyVkSet[_sig]) revert SubsidyVkNotSet(); - - vk = subsidyVks[_sig]; - } - - /// @inheritdoc IVkRegistry - function getSubsidyVk( - uint256 _stateTreeDepth, - uint256 _intStateTreeDepth, - uint256 _voteOptionTreeDepth - ) public view returns (VerifyingKey memory vk) { - uint256 sig = genSubsidyVkSig(_stateTreeDepth, _intStateTreeDepth, _voteOptionTreeDepth); - - vk = getSubsidyVkBySig(sig); - } } diff --git a/contracts/contracts/interfaces/ITallySubsidyFactory.sol b/contracts/contracts/interfaces/ITallyFactory.sol similarity index 72% rename from contracts/contracts/interfaces/ITallySubsidyFactory.sol rename to contracts/contracts/interfaces/ITallyFactory.sol index c772329db4..9ef226cbd4 100644 --- a/contracts/contracts/interfaces/ITallySubsidyFactory.sol +++ b/contracts/contracts/interfaces/ITallyFactory.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.10; -/// @title ITallySubsidyFactory -/// @notice TallySubsidyFactory interface -interface ITallySubsidyFactory { - /// @notice Deploy a new Tally or Subsidy contract and return the address. +/// @title ITallyFactory +/// @notice TallyFactory interface +interface ITallyFactory { + /// @notice Deploy a new Tally contract and return the address. /// @param _verifier Verifier contract /// @param _vkRegistry VkRegistry contract /// @param _poll Poll contract diff --git a/contracts/contracts/interfaces/IVkRegistry.sol b/contracts/contracts/interfaces/IVkRegistry.sol index 24c2f5ab97..8bcc222cae 100644 --- a/contracts/contracts/interfaces/IVkRegistry.sol +++ b/contracts/contracts/interfaces/IVkRegistry.sol @@ -29,15 +29,4 @@ interface IVkRegistry { uint256 _voteOptionTreeDepth, uint256 _messageBatchSize ) external view returns (SnarkCommon.VerifyingKey memory); - - /// @notice Get the subsidy verifying key - /// @param _stateTreeDepth The state tree depth - /// @param _intStateTreeDepth The intermediate state tree depth - /// @param _voteOptionTreeDepth The vote option tree depth - /// @return The verifying key - function getSubsidyVk( - uint256 _stateTreeDepth, - uint256 _intStateTreeDepth, - uint256 _voteOptionTreeDepth - ) external view returns (SnarkCommon.VerifyingKey memory); } diff --git a/contracts/contracts/utilities/CommonUtilities.sol b/contracts/contracts/utilities/CommonUtilities.sol index 08ade0d0ef..901d017ad4 100644 --- a/contracts/contracts/utilities/CommonUtilities.sol +++ b/contracts/contracts/utilities/CommonUtilities.sol @@ -6,11 +6,11 @@ import { IPoll } from "../interfaces/IPoll.sol"; /// @title CommonUtilities /// @notice A contract that holds common utilities /// which are to be used by multiple contracts -/// namely Subsidy, Tally and MessageProcessor +/// namely Tally and MessageProcessor contract CommonUtilities { error VotingPeriodNotPassed(); - /// @notice common function for MessageProcessor, Tally and Subsidy + /// @notice common function for MessageProcessor, and Tally /// @param _poll the poll to be checked function _votingPeriodOver(IPoll _poll) internal view { (uint256 deployTime, uint256 duration) = _poll.getDeployTimeAndDuration(); diff --git a/contracts/package.json b/contracts/package.json index 6b93a0c3b7..7164b6b2bf 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -47,7 +47,6 @@ "test:hasherBenchmarks": "pnpm run test ./tests/HasherBenchmarks.test.ts", "test:vkRegistry": "pnpm run test ./tests/VkRegistry.test.ts", "test:pollFactory": "pnpm run test ./tests/PollFactory.test.ts", - "test:subsidy": "pnpm run test ./tests/Subsidy.test.ts", "test:eas_gatekeeper": "pnpm run test ./tests/EASGatekeeper.test.ts", "test:hats_gatekeeper": "pnpm run test ./tests/HatsGatekeeper.test.ts", "deploy": "hardhat deploy-full", diff --git a/contracts/tasks/deploy/maci/10-maci.ts b/contracts/tasks/deploy/maci/09-maci.ts similarity index 95% rename from contracts/tasks/deploy/maci/10-maci.ts rename to contracts/tasks/deploy/maci/09-maci.ts index 5c99c1523a..03da07c72f 100644 --- a/contracts/tasks/deploy/maci/10-maci.ts +++ b/contracts/tasks/deploy/maci/09-maci.ts @@ -54,7 +54,7 @@ deployment hre.network.name, ); const tallyFactoryContractAddress = storage.mustGetAddress(EContracts.TallyFactory, hre.network.name); - const subsidyFactoryContractAddress = storage.mustGetAddress(EContracts.SubsidyFactory, hre.network.name); + const stateTreeDepth = deployment.getDeployConfigField(EContracts.MACI, "stateTreeDepth") ?? DEFAULT_STATE_TREE_DEPTH; @@ -63,7 +63,6 @@ deployment pollFactoryContractAddress, messageProcessorFactoryContractAddress, tallyFactoryContractAddress, - subsidyFactoryContractAddress, gatekeeperContractAddress, constantInitialVoiceCreditProxyContractAddress, topupCreditContractAddress, @@ -87,7 +86,6 @@ deployment pollFactoryContractAddress, messageProcessorFactoryContractAddress, tallyFactoryContractAddress, - subsidyFactoryContractAddress, gatekeeperContractAddress, constantInitialVoiceCreditProxyContractAddress, topupCreditContractAddress, diff --git a/contracts/tasks/deploy/maci/09-subsidyFactory.ts b/contracts/tasks/deploy/maci/09-subsidyFactory.ts deleted file mode 100644 index 455bdacbf0..0000000000 --- a/contracts/tasks/deploy/maci/09-subsidyFactory.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { ContractStorage } from "../../helpers/ContractStorage"; -import { Deployment } from "../../helpers/Deployment"; -import { EContracts, IDeployParams } from "../../helpers/types"; - -const deployment = Deployment.getInstance(); -const storage = ContractStorage.getInstance(); - -/** - * Deploy step registration and task itself - */ -deployment - .deployTask("full:deploy-subsidy-factory", "Deploy subsidy factory") - .setAction(async ({ incremental }: IDeployParams, hre) => { - deployment.setHre(hre); - const deployer = await deployment.getDeployer(); - - const subsidyFactoryContractAddress = storage.getAddress(EContracts.SubsidyFactory, hre.network.name); - - if (incremental && subsidyFactoryContractAddress) { - return; - } - - const poseidonT3ContractAddress = storage.mustGetAddress(EContracts.PoseidonT3, hre.network.name); - const poseidonT4ContractAddress = storage.mustGetAddress(EContracts.PoseidonT4, hre.network.name); - const poseidonT5ContractAddress = storage.mustGetAddress(EContracts.PoseidonT5, hre.network.name); - const poseidonT6ContractAddress = storage.mustGetAddress(EContracts.PoseidonT6, hre.network.name); - - const linkedSubsidyFactoryContract = await deployment.linkPoseidonLibraries( - EContracts.SubsidyFactory, - poseidonT3ContractAddress, - poseidonT4ContractAddress, - poseidonT5ContractAddress, - poseidonT6ContractAddress, - deployer, - ); - - const subsidyFactoryContract = await deployment.deployContractWithLinkedLibraries(linkedSubsidyFactoryContract); - - await storage.register({ - id: EContracts.SubsidyFactory, - contract: subsidyFactoryContract, - args: [], - network: hre.network.name, - }); - }); diff --git a/contracts/tasks/deploy/maci/11-vkRegistry.ts b/contracts/tasks/deploy/maci/10-vkRegistry.ts similarity index 77% rename from contracts/tasks/deploy/maci/11-vkRegistry.ts rename to contracts/tasks/deploy/maci/10-vkRegistry.ts index ff0a5b5282..5e29940c67 100644 --- a/contracts/tasks/deploy/maci/11-vkRegistry.ts +++ b/contracts/tasks/deploy/maci/10-vkRegistry.ts @@ -36,13 +36,11 @@ deployment "processMessagesZkey", ); const tallyVotesZkeyPath = deployment.getDeployConfigField(EContracts.VkRegistry, "tallyVotesZkey"); - const subsidyZkeyPath = deployment.getDeployConfigField(EContracts.VkRegistry, "subsidyZkey"); - const [processVk, tallyVk, subsidyVk] = await Promise.all([ + const [processVk, tallyVk] = await Promise.all([ extractVk(processMessagesZkeyPath), extractVk(tallyVotesZkeyPath), - subsidyZkeyPath && extractVk(subsidyZkeyPath), - ]).then((vks) => vks.map((vk) => (vk ? VerifyingKey.fromObj(vk) : null))); + ]).then((vks) => vks.map((vk) => VerifyingKey.fromObj(vk))); const vkRegistryContract = await deployment.deployContract(EContracts.VkRegistry, deployer); @@ -53,22 +51,11 @@ deployment messageTreeDepth, voteOptionTreeDepth, 5 ** messageBatchDepth, - processVk!.asContractParam() as IVerifyingKeyStruct, - tallyVk!.asContractParam() as IVerifyingKeyStruct, + processVk.asContractParam() as IVerifyingKeyStruct, + tallyVk.asContractParam() as IVerifyingKeyStruct, ) .then((tx) => tx.wait()); - if (subsidyVk) { - await vkRegistryContract - .setSubsidyKeys( - stateTreeDepth, - intStateTreeDepth, - voteOptionTreeDepth, - subsidyVk.asContractParam() as IVerifyingKeyStruct, - ) - .then((tx) => tx.wait()); - } - await storage.register({ id: EContracts.VkRegistry, contract: vkRegistryContract, diff --git a/contracts/tasks/deploy/poll/01-poll.ts b/contracts/tasks/deploy/poll/01-poll.ts index bfca51b150..1cefb0b755 100644 --- a/contracts/tasks/deploy/poll/01-poll.ts +++ b/contracts/tasks/deploy/poll/01-poll.ts @@ -1,5 +1,4 @@ /* eslint-disable no-console */ -import { ZeroAddress } from "ethers"; import { PubKey } from "maci-domainobjs"; import { AccQueueBinary, MACI, Poll } from "../../../typechain-types"; @@ -53,12 +52,12 @@ deployment.deployTask("poll:deploy-poll", "Deploy poll").setAction(async (_, hre const messageTreeSubDepth = deployment.getDeployConfigField(EContracts.VkRegistry, "messageBatchDepth"); const messageTreeDepth = deployment.getDeployConfigField(EContracts.VkRegistry, "messageTreeDepth"); const voteOptionTreeDepth = deployment.getDeployConfigField(EContracts.VkRegistry, "voteOptionTreeDepth"); - const subsidyEnabled = deployment.getDeployConfigField(EContracts.Poll, "subsidyEnabled") ?? false; + const useQuadraticVoting = deployment.getDeployConfigField(EContracts.Poll, "useQuadraticVoting") ?? false; const unserializedKey = PubKey.deserialize(coordinatorPubkey); - const [pollContractAddress, messageProcessorContractAddress, tallyContractAddress, subsidyContractAddress] = + const [pollContractAddress, messageProcessorContractAddress, tallyContractAddress] = await maciContract.deployPoll.staticCall( pollDuration, { @@ -70,7 +69,6 @@ deployment.deployTask("poll:deploy-poll", "Deploy poll").setAction(async (_, hre unserializedKey.asContractParam(), verifierContractAddress, vkRegistryContractAddress, - subsidyEnabled, ); const tx = await maciContract.deployPoll( @@ -84,7 +82,6 @@ deployment.deployTask("poll:deploy-poll", "Deploy poll").setAction(async (_, hre unserializedKey.asContractParam(), verifierContractAddress, vkRegistryContractAddress, - subsidyEnabled, ); const receipt = await tx.wait(); @@ -156,19 +153,4 @@ deployment.deployTask("poll:deploy-poll", "Deploy poll").setAction(async (_, hre network: hre.network.name, }), ]); - - if (subsidyContractAddress && subsidyContractAddress !== ZeroAddress) { - const subsidyContract = await deployment.getContract({ - name: EContracts.Subsidy, - address: subsidyContractAddress, - }); - - await storage.register({ - id: EContracts.Subsidy, - key: `poll-${pollId}`, - contract: subsidyContract, - args: [verifierContractAddress, vkRegistryContractAddress, pollContractAddress, messageProcessorContractAddress], - network: hre.network.name, - }); - } }); diff --git a/contracts/tasks/helpers/ProofGenerator.ts b/contracts/tasks/helpers/ProofGenerator.ts index ccb148b197..6375628e8e 100644 --- a/contracts/tasks/helpers/ProofGenerator.ts +++ b/contracts/tasks/helpers/ProofGenerator.ts @@ -15,7 +15,7 @@ import { genMaciStateFromContract } from "../../ts/genMaciState"; import { asHex } from "../../ts/utils"; /** - * Proof generator class for message processing, subsidy and tally. + * Proof generator class for message processing and tally. */ export class ProofGenerator { /** @@ -43,11 +43,6 @@ export class ProofGenerator { */ private tallyOutputFile: string; - /** - * The file to store the subsidy proof - */ - private subsidyOutputFile?: string; - /** * Message processing circuit files */ @@ -58,11 +53,6 @@ export class ProofGenerator { */ private tally: ICircuitFiles; - /** - * Subsidy circuit files - */ - private subsidy?: ICircuitFiles; - /** * Whether to use quadratic voting or not */ @@ -162,8 +152,6 @@ export class ProofGenerator { tallyContractAddress, outputDir, tallyOutputFile, - subsidyOutputFile, - subsidy, useQuadraticVoting, }: IProofGeneratorParams) { this.poll = poll; @@ -171,11 +159,9 @@ export class ProofGenerator { this.tallyContractAddress = tallyContractAddress; this.outputDir = outputDir; this.tallyOutputFile = tallyOutputFile; - this.subsidyOutputFile = subsidyOutputFile; this.mp = mp; this.tally = tally; this.rapidsnark = rapidsnark; - this.subsidy = subsidy; this.useQuadraticVoting = useQuadraticVoting; } @@ -220,59 +206,6 @@ export class ProofGenerator { return proofs; } - /** - * Generate subsidy proofs - * - * @throws error is there is no subsidy or subsidy output file properties - * @returns subsidy proofs - */ - async generateSubsidyProofs(): Promise { - if (!this.subsidy || !this.subsidyOutputFile) { - throw new Error("Subsidy args was not set"); - } - - performance.mark("subsidy-proofs-start"); - - const proofs: Proof[] = []; - const { subsidyBatchSize } = this.poll.batchSizes; - const numLeaves = this.poll.stateLeaves.length; - const totalSubsidyBatches = Math.ceil(numLeaves / subsidyBatchSize) ** 2; - - let numBatchesCalulated = 0; - let subsidyCircuitInputs: CircuitInputs; - - while (this.poll.hasUnfinishedSubsidyCalculation()) { - subsidyCircuitInputs = this.poll.subsidyPerBatch() as unknown as CircuitInputs; - // eslint-disable-next-line no-await-in-loop - await this.generateProofs(subsidyCircuitInputs, this.subsidy, `subsidy_${numBatchesCalulated}.json`).then( - (data) => proofs.push(...data), - ); - numBatchesCalulated += 1; - - console.log(`Progress: ${numBatchesCalulated} / ${totalSubsidyBatches}`); - } - - const fileData = { - provider: process.env.ETH_PROVIDER, - maci: this.maciContractAddress, - pollId: this.poll.pollId.toString(), - newSubsidyCommitment: asHex(subsidyCircuitInputs!.newSubsidyCommitment as BigNumberish), - results: { - subsidy: this.poll.subsidy.map((x) => x.toString()), - salt: asHex(subsidyCircuitInputs!.newSubsidySalt as BigNumberish), - }, - }; - - // store it - fs.writeFileSync(this.subsidyOutputFile, JSON.stringify(fileData, null, 4)); - console.log(`Subsidy file:\n${JSON.stringify(fileData, null, 4)}\n`); - - performance.mark("subsidy-proofs-end"); - performance.measure("Generate subsidy proofs", "subsidy-proofs-start", "subsidy-proofs-end"); - - return proofs; - } - /** * Generate tally proofs * diff --git a/contracts/tasks/helpers/Prover.ts b/contracts/tasks/helpers/Prover.ts index 5551a428fc..4067b0994f 100644 --- a/contracts/tasks/helpers/Prover.ts +++ b/contracts/tasks/helpers/Prover.ts @@ -8,7 +8,6 @@ import type { MACI, MessageProcessor, Poll, - Subsidy, Tally, TallyNonQv, Verifier, @@ -22,7 +21,7 @@ import { STATE_TREE_ARITY } from "./constants"; import { IProverParams } from "./types"; /** - * Prover class is designed to prove message processing, tally and subsidy (optional) proofs on-chain. + * Prover class is designed to prove message processing and tally proofs on-chain. */ export class Prover { /** @@ -60,11 +59,6 @@ export class Prover { */ private tallyContract: Tally | TallyNonQv; - /** - * Subsidy contract typechain wrapper - */ - private subsidyContract?: Subsidy; - /** * Initialize class properties * @@ -77,7 +71,6 @@ export class Prover { maciContract, vkRegistryContract, verifierContract, - subsidyContract, tallyContract, }: IProverParams) { this.pollContract = pollContract; @@ -86,7 +79,6 @@ export class Prover { this.maciContract = maciContract; this.vkRegistryContract = vkRegistryContract; this.verifierContract = verifierContract; - this.subsidyContract = subsidyContract; this.tallyContract = tallyContract; } @@ -257,91 +249,6 @@ export class Prover { } } - /** - * Prove subsidy on-chain - * - * @param proofs - subsidy proofs - */ - async proveSubsidy(proofs: Proof[]): Promise { - if (!this.subsidyContract || proofs.length === 0) { - return; - } - - const [treeDepths, numSignUpsAndMessages, r, c] = await Promise.all([ - this.pollContract.treeDepths(), - this.pollContract.numSignUpsAndMessages(), - this.subsidyContract.rbi(), - this.subsidyContract.cbi(), - ]); - - const numSignUps = Number(numSignUpsAndMessages[0]); - const subsidyBatchSize = STATE_TREE_ARITY ** Number(treeDepths.intStateTreeDepth); - // subsidy calculations if any subsidy proofs are provided - let cbi = Number(c); - let rbi = Number(r); - - const num1DBatches = Math.ceil(numSignUps / subsidyBatchSize); - let subsidyBatchNum = rbi * num1DBatches + cbi; - const totalBatchNum = (num1DBatches * (num1DBatches + 1)) / 2; - - console.log(`number of subsidy batch processed: ${subsidyBatchNum}, numleaf=${numSignUps}`); - - // process all batches - for (let i = subsidyBatchNum; i < totalBatchNum; i += 1) { - if (i === 0) { - await this.subsidyContract.updateSbCommitment().then((tx) => tx.wait()); - } - - const { proof, circuitInputs, publicInputs } = proofs[i]; - - // ensure the commitment matches - const subsidyCommitmentOnChain = await this.subsidyContract.subsidyCommitment(); - this.validateCommitment(circuitInputs.currentSubsidyCommitment as BigNumberish, subsidyCommitmentOnChain); - - const packedValsOnChain = BigInt(await this.subsidyContract.genSubsidyPackedVals(numSignUps)); - this.validatePackedValues(circuitInputs.packedVals as BigNumberish, packedValsOnChain); - - // ensure the state and ballot root commitment matches - const currentSbCommitmentOnChain = await this.subsidyContract.sbCommitment(); - this.validateCommitment(circuitInputs.currentSbCommitment as BigNumberish, currentSbCommitmentOnChain); - - const publicInputHashOnChain = await this.subsidyContract.genSubsidyPublicInputHash( - numSignUps, - circuitInputs.newSubsidyCommitment as BigNumberish, - ); - - this.validatePublicInput(publicInputs[0] as BigNumberish, publicInputHashOnChain.toString()); - - // format the proof so it can be verify on chain - const formattedProof = formatProofForVerifierContract(proof); - - // verify the proof on chain and set the new subsidy commitment - const receipt = await this.subsidyContract - .updateSubsidy(circuitInputs.newSubsidyCommitment as BigNumberish, formattedProof) - .then((tx) => tx.wait()); - - if (receipt?.status !== 1) { - throw new Error("updateSubsidy() failed."); - } - - console.log(`Transaction hash: ${receipt.hash}`); - console.log(`Progress: ${subsidyBatchNum + 1} / ${totalBatchNum}`); - - const [nrbi, ncbi] = await Promise.all([ - this.subsidyContract.rbi().then(Number), - this.subsidyContract.cbi().then(Number), - ]); - - rbi = nrbi; - cbi = ncbi; - subsidyBatchNum = rbi * num1DBatches + cbi; - } - - if (subsidyBatchNum === totalBatchNum) { - console.log("All subsidy calculation proofs have been submitted."); - } - } - /** * Prove tally on-chain * diff --git a/contracts/tasks/helpers/types.ts b/contracts/tasks/helpers/types.ts index b1c82d2632..772987fa84 100644 --- a/contracts/tasks/helpers/types.ts +++ b/contracts/tasks/helpers/types.ts @@ -3,7 +3,6 @@ import type { MACI, MessageProcessor, Poll, - Subsidy, Tally, TallyNonQv, Verifier, @@ -119,26 +118,6 @@ export interface IProveParams { */ tallyWasm?: string; - /** - * The file to store the subsidy proof - */ - subsidyFile?: string; - - /** - * The path to the subsidy zkey file - */ - subsidyZkey?: string; - - /** - * The path to the subsidy witnessgen binary - */ - subsidyWitgen?: string; - - /** - * The path to the subsidy wasm file - */ - subsidyWasm?: string; - /** * Whether to use quadratic voting or not */ @@ -199,11 +178,6 @@ export interface IProofGeneratorParams { */ tallyOutputFile: string; - /** - * File to store the subsidy proof - */ - subsidyOutputFile?: string; - /** * Message processing circuit files */ @@ -214,11 +188,6 @@ export interface IProofGeneratorParams { */ tally: ICircuitFiles; - /** - * Subsidy circuit files - */ - subsidy?: ICircuitFiles; - /** * Path to the rapidsnark binary */ @@ -358,11 +327,6 @@ export interface IProverParams { * Tally contract typechain wrapper */ tallyContract: Tally | TallyNonQv; - - /** - * Subsidy contract typechain wrapper - */ - subsidyContract?: Subsidy; } /** @@ -523,7 +487,6 @@ export enum EContracts { MessageProcessorFactory = "MessageProcessorFactory", TallyFactory = "TallyFactory", TallyNonQvFactory = "TallyNonQvFactory", - SubsidyFactory = "SubsidyFactory", PoseidonT3 = "PoseidonT3", PoseidonT4 = "PoseidonT4", PoseidonT5 = "PoseidonT5", @@ -533,7 +496,6 @@ export enum EContracts { Tally = "Tally", TallyNonQv = "TallyNonQv", MessageProcessor = "MessageProcessor", - Subsidy = "Subsidy", AccQueue = "AccQueue", AccQueueQuinaryBlankSl = "AccQueueQuinaryBlankSl", AccQueueQuinaryMaci = "AccQueueQuinaryMaci", diff --git a/contracts/tasks/runner/prove.ts b/contracts/tasks/runner/prove.ts index 5bf4a7cb80..2e28c073f6 100644 --- a/contracts/tasks/runner/prove.ts +++ b/contracts/tasks/runner/prove.ts @@ -8,7 +8,6 @@ import fs from "fs"; import type { Proof } from "../../ts/types"; import type { VkRegistry, - Subsidy, Verifier, MACI, Poll, @@ -39,10 +38,6 @@ task("prove", "Command to generate proof and prove the result of a poll on-chain .addParam("tallyZkey", "Tally zkey file path", undefined, types.string) .addOptionalParam("tallyWitgen", "Tally witgen binary path", undefined, types.string) .addOptionalParam("tallyWasm", "Tally wasm file path", undefined, types.string) - .addOptionalParam("subsidyFile", "The file to store the subsidy proof", undefined, types.string) - .addOptionalParam("subsidyZkey", "Subsidy zkey file path", undefined, types.string) - .addOptionalParam("subsidyWitgen", "Subsidy witgen binary path", undefined, types.string) - .addOptionalParam("subsidyWasm", "Subsidy wasm file path", undefined, types.string) .addOptionalParam("stateFile", "The file with the serialized maci state", undefined, types.string) .addFlag("useQuadraticVoting", "Whether to use quadratic voting or not") .addOptionalParam("startBlock", "The block number to start fetching logs from", undefined, types.int) @@ -64,10 +59,6 @@ task("prove", "Command to generate proof and prove the result of a poll on-chain tallyWitgen, tallyWasm, tallyFile, - subsidyFile, - subsidyZkey, - subsidyWitgen, - subsidyWasm, useQuadraticVoting, startBlock, blocksPerBatch, @@ -152,8 +143,6 @@ task("prove", "Command to generate proof and prove the result of a poll on-chain throw new Error(`Poll ${poll} not found`); } - const subsidyContractAddress = storage.getAddress(EContracts.Subsidy, network.name, `poll-${poll.toString()}`); - const mpContract = await deployment.getContract({ name: EContracts.MessageProcessor, key: `poll-${poll.toString()}`, @@ -171,15 +160,6 @@ task("prove", "Command to generate proof and prove the result of a poll on-chain }); const tallyContractAddress = await tallyContract.getAddress(); - let subsidyContract: Subsidy | undefined; - - if (subsidyContractAddress) { - subsidyContract = await deployment.getContract({ - name: EContracts.Subsidy, - key: `poll-${poll.toString()}`, - }); - } - const proofGenerator = new ProofGenerator({ poll: foundPoll, maciContractAddress, @@ -195,16 +175,7 @@ task("prove", "Command to generate proof and prove the result of a poll on-chain witgen: processWitgen, wasm: processWasm, }, - subsidy: - subsidyZkey && subsidyWitgen - ? { - zkey: subsidyZkey, - witgen: subsidyWitgen, - wasm: subsidyWasm, - } - : undefined, outputDir, - subsidyOutputFile: subsidyFile, tallyOutputFile: tallyFile, useQuadraticVoting, }); @@ -212,7 +183,6 @@ task("prove", "Command to generate proof and prove the result of a poll on-chain const data = { processProofs: [] as Proof[], tallyProofs: [] as Proof[], - subsidyProofs: [] as Proof[], }; const prover = new Prover({ @@ -223,18 +193,11 @@ task("prove", "Command to generate proof and prove the result of a poll on-chain vkRegistryContract, verifierContract, tallyContract, - subsidyContract, }); data.processProofs = await proofGenerator.generateMpProofs(); await prover.proveMessageProcessing(data.processProofs); - // subsidy calculations are not mandatory - if (subsidyFile) { - data.subsidyProofs = await proofGenerator.generateSubsidyProofs(); - await prover.proveSubsidy(data.subsidyProofs); - } - data.tallyProofs = await proofGenerator.generateTallyProofs(network); await prover.proveTally(data.tallyProofs); diff --git a/contracts/tests/MACI.test.ts b/contracts/tests/MACI.test.ts index 38b80f39ed..4141fa375d 100644 --- a/contracts/tests/MACI.test.ts +++ b/contracts/tests/MACI.test.ts @@ -166,7 +166,6 @@ describe("MACI", () => { coordinator.pubKey.asContractParam() as { x: BigNumberish; y: BigNumberish }, verifierContract, vkRegistryContract, - false, { gasLimit: 10000000 }, ); const receipt = await tx.wait(); @@ -212,7 +211,6 @@ describe("MACI", () => { coordinator.pubKey.asContractParam(), verifierContract, vkRegistryContract, - false, { gasLimit: 10000000, }, diff --git a/contracts/tests/MessageProcessor.test.ts b/contracts/tests/MessageProcessor.test.ts index 33c17b0e3f..d7d51adf43 100644 --- a/contracts/tests/MessageProcessor.test.ts +++ b/contracts/tests/MessageProcessor.test.ts @@ -62,7 +62,6 @@ describe("MessageProcessor", () => { coordinator.pubKey.asContractParam(), verifierContract, vkRegistryContract, - false, { gasLimit: 10000000, }, diff --git a/contracts/tests/Poll.test.ts b/contracts/tests/Poll.test.ts index a44a867c17..d2d2444ec4 100644 --- a/contracts/tests/Poll.test.ts +++ b/contracts/tests/Poll.test.ts @@ -54,7 +54,6 @@ describe("Poll", () => { coordinator.pubKey.asContractParam(), verifierContract, vkRegistryContract, - false, { gasLimit: 10000000, }, diff --git a/contracts/tests/Subsidy.test.ts b/contracts/tests/Subsidy.test.ts deleted file mode 100644 index e81200f634..0000000000 --- a/contracts/tests/Subsidy.test.ts +++ /dev/null @@ -1,207 +0,0 @@ -/* eslint-disable no-underscore-dangle */ -import { expect } from "chai"; -import { BaseContract, Signer } from "ethers"; -import { EthereumProvider } from "hardhat/types"; -import { MaciState, Poll, packSubsidySmallVals, IProcessMessagesCircuitInputs, ISubsidyCircuitInputs } from "maci-core"; -import { NOTHING_UP_MY_SLEEVE } from "maci-crypto"; -import { Keypair, Message, PubKey } from "maci-domainobjs"; - -import { parseArtifact } from "../ts/abi"; -import { IVerifyingKeyStruct } from "../ts/types"; -import { getDefaultSigner } from "../ts/utils"; -import { MACI, Poll as PollContract, MessageProcessor, Subsidy, Verifier, VkRegistry } from "../typechain-types"; - -import { - STATE_TREE_DEPTH, - duration, - maxValues, - messageBatchSize, - testProcessVk, - testTallyVk, - treeDepths, -} from "./constants"; -import { timeTravel, deployTestContracts } from "./utils"; - -describe("Subsidy", () => { - let signer: Signer; - let maciContract: MACI; - let pollContract: PollContract; - let subsidyContract: Subsidy; - let mpContract: MessageProcessor; - let verifierContract: Verifier; - let vkRegistryContract: VkRegistry; - - const coordinator = new Keypair(); - const maciState = new MaciState(STATE_TREE_DEPTH); - - const [pollAbi] = parseArtifact("Poll"); - const [mpAbi] = parseArtifact("MessageProcessor"); - const [subsidyAbi] = parseArtifact("Subsidy"); - - let pollId: bigint; - let poll: Poll; - - let generatedInputs: IProcessMessagesCircuitInputs; - - before(async () => { - signer = await getDefaultSigner(); - - const r = await deployTestContracts(100, STATE_TREE_DEPTH, signer, true); - maciContract = r.maciContract; - verifierContract = r.mockVerifierContract as Verifier; - vkRegistryContract = r.vkRegistryContract; - - // deploy a poll - // deploy on chain poll - const tx = await maciContract.deployPoll( - duration, - treeDepths, - coordinator.pubKey.asContractParam(), - verifierContract, - vkRegistryContract, - true, - { - gasLimit: 10000000, - }, - ); - const receipt = await tx.wait(); - - const block = await signer.provider!.getBlock(receipt!.blockHash); - const deployTime = block!.timestamp; - - expect(receipt?.status).to.eq(1); - const iface = maciContract.interface; - - // parse DeployPoll log - const logMPTally = receipt!.logs[receipt!.logs.length - 1]; - const MPTallyEvent = iface.parseLog(logMPTally as unknown as { topics: string[]; data: string }) as unknown as { - args: { - _pollId: bigint; - pollAddr: { - poll: string; - messageProcessor: string; - tally: string; - subsidy: string; - }; - }; - name: string; - }; - expect(MPTallyEvent.name).to.eq("DeployPoll"); - - pollId = MPTallyEvent.args._pollId; - - const pollContractAddress = await maciContract.getPoll(pollId); - pollContract = new BaseContract(pollContractAddress, pollAbi, signer) as PollContract; - const mpContractAddress = MPTallyEvent.args.pollAddr.messageProcessor; - mpContract = new BaseContract(mpContractAddress, mpAbi, signer) as MessageProcessor; - const subsidyContractAddress = MPTallyEvent.args.pollAddr.subsidy; - subsidyContract = new BaseContract(subsidyContractAddress, subsidyAbi, signer) as Subsidy; - - // deploy local poll - const p = maciState.deployPoll(BigInt(deployTime + duration), maxValues, treeDepths, messageBatchSize, coordinator); - expect(p.toString()).to.eq(pollId.toString()); - // publish the NOTHING_UP_MY_SLEEVE message - const messageData = [NOTHING_UP_MY_SLEEVE, BigInt(0)]; - for (let i = 2; i < 10; i += 1) { - messageData.push(BigInt(0)); - } - const message = new Message(BigInt(1), messageData); - const padKey = new PubKey([ - BigInt("10457101036533406547632367118273992217979173478358440826365724437999023779287"), - BigInt("19824078218392094440610104313265183977899662750282163392862422243483260492317"), - ]); - - // save the poll - poll = maciState.polls.get(pollId)!; - - poll.publishMessage(message, padKey); - - // update the poll state - poll.updatePoll(BigInt(maciState.stateLeaves.length)); - - // process messages locally - generatedInputs = poll.processMessages(pollId); - - // set the verification keys on the vk smart contract - await vkRegistryContract.setVerifyingKeys( - STATE_TREE_DEPTH, - treeDepths.intStateTreeDepth, - treeDepths.messageTreeDepth, - treeDepths.voteOptionTreeDepth, - messageBatchSize, - testProcessVk.asContractParam() as IVerifyingKeyStruct, - testTallyVk.asContractParam() as IVerifyingKeyStruct, - { gasLimit: 1000000 }, - ); - await vkRegistryContract.setSubsidyKeys( - STATE_TREE_DEPTH, - treeDepths.intStateTreeDepth, - treeDepths.voteOptionTreeDepth, - testProcessVk.asContractParam() as IVerifyingKeyStruct, - { gasLimit: 1000000 }, - ); - }); - - it("should not be possible to update subsidy before the poll has ended", async () => { - await expect(subsidyContract.updateSubsidy(0, [0, 0, 0, 0, 0, 0, 0, 0])).to.be.revertedWithCustomError( - subsidyContract, - "VotingPeriodNotPassed", - ); - }); - - it("genSubsidyPackedVals() should generate the correct value", async () => { - const onChainPackedVals = BigInt(await subsidyContract.genSubsidyPackedVals(0)); - const packedVals = packSubsidySmallVals(0, 0, 0); - expect(onChainPackedVals.toString()).to.eq(packedVals.toString()); - }); - - it("updateSbCommitment() should revert when the messages have not been processed yet", async () => { - // go forward in time - await timeTravel(signer.provider! as unknown as EthereumProvider, duration + 1); - - await expect(subsidyContract.updateSbCommitment()).to.be.revertedWithCustomError( - subsidyContract, - "ProcessingNotComplete", - ); - }); - - it("updateSubsidy() should fail as the messages have not been processed yet", async () => { - await expect(subsidyContract.updateSubsidy(0, [0, 0, 0, 0, 0, 0, 0, 0])).to.be.revertedWithCustomError( - subsidyContract, - "ProcessingNotComplete", - ); - }); - - describe("after merging acc queues", () => { - let subsidyGeneratedInputs: ISubsidyCircuitInputs; - before(async () => { - await pollContract.mergeMaciStateAqSubRoots(0, pollId); - await pollContract.mergeMaciStateAq(0); - - await pollContract.mergeMessageAqSubRoots(0); - await pollContract.mergeMessageAq(); - subsidyGeneratedInputs = poll.subsidyPerBatch(); - }); - it("updateSubsidy() should update the tally commitment", async () => { - // do the processing on the message processor contract - await mpContract.processMessages(generatedInputs.newSbCommitment, [0, 0, 0, 0, 0, 0, 0, 0]); - - const tx = await subsidyContract.updateSubsidy( - subsidyGeneratedInputs.newSubsidyCommitment, - [0, 0, 0, 0, 0, 0, 0, 0], - ); - - const receipt = await tx.wait(); - expect(receipt?.status).to.eq(1); - - const onChainNewTallyCommitment = await subsidyContract.subsidyCommitment(); - - expect(subsidyGeneratedInputs.newSubsidyCommitment).to.eq(onChainNewTallyCommitment.toString()); - }); - it("updateSubsidy() should revert when votes have already been tallied", async () => { - await expect( - subsidyContract.updateSubsidy(subsidyGeneratedInputs.newSubsidyCommitment, [0, 0, 0, 0, 0, 0, 0, 0]), - ).to.be.revertedWithCustomError(subsidyContract, "AllSubsidyCalculated"); - }); - }); -}); diff --git a/contracts/tests/Tally.test.ts b/contracts/tests/Tally.test.ts index ead2378ca8..0896f2d0eb 100644 --- a/contracts/tests/Tally.test.ts +++ b/contracts/tests/Tally.test.ts @@ -72,7 +72,6 @@ describe("TallyVotes", () => { coordinator.pubKey.asContractParam(), verifierContract, vkRegistryContract, - false, { gasLimit: 10000000, }, @@ -253,7 +252,6 @@ describe("TallyVotes", () => { coordinator.pubKey.asContractParam(), verifierContract, vkRegistryContract, - false, { gasLimit: 10000000, }, @@ -394,7 +392,6 @@ describe("TallyVotes", () => { coordinator.pubKey.asContractParam(), verifierContract, vkRegistryContract, - false, { gasLimit: 10000000, }, diff --git a/contracts/tests/TallyNonQv.test.ts b/contracts/tests/TallyNonQv.test.ts index 5ea9f2aa82..dddf67f16c 100644 --- a/contracts/tests/TallyNonQv.test.ts +++ b/contracts/tests/TallyNonQv.test.ts @@ -72,7 +72,6 @@ describe("TallyVotesNonQv", () => { coordinator.pubKey.asContractParam(), verifierContract, vkRegistryContract, - false, { gasLimit: 10000000, }, diff --git a/contracts/tests/VkRegistry.test.ts b/contracts/tests/VkRegistry.test.ts index b255874b39..be0c889578 100644 --- a/contracts/tests/VkRegistry.test.ts +++ b/contracts/tests/VkRegistry.test.ts @@ -67,18 +67,6 @@ describe("VkRegistry", () => { const receipt = await tx.wait(); expect(receipt?.status).to.eq(1); }); - - it("should allow to set the subsidy vks", async () => { - const tx = await vkRegistryContract.setSubsidyKeys( - stateTreeDepth, - treeDepths.intStateTreeDepth, - treeDepths.voteOptionTreeDepth, - testProcessVk.asContractParam() as IVerifyingKeyStruct, - { gasLimit: 1000000 }, - ); - const receipt = await tx.wait(); - expect(receipt?.status).to.eq(1); - }); }); describe("hasVks", () => { @@ -125,27 +113,6 @@ describe("VkRegistry", () => { ).to.eq(false); }); }); - - describe("hasSubsidyVk", () => { - it("should return true for the subsidy vk", async () => { - expect( - await vkRegistryContract.hasSubsidyVk( - stateTreeDepth, - treeDepths.intStateTreeDepth, - treeDepths.voteOptionTreeDepth, - ), - ).to.eq(true); - }); - it("should return false for a non-existing vk", async () => { - expect( - await vkRegistryContract.hasSubsidyVk( - stateTreeDepth + 2, - treeDepths.intStateTreeDepth, - treeDepths.voteOptionTreeDepth, - ), - ).to.eq(false); - }); - }); }); describe("genSignatures", () => { @@ -173,17 +140,5 @@ describe("VkRegistry", () => { compareVks(testTallyVk, vk); }); }); - - describe("genSubsidyVkSig", () => { - it("should generate a valid signature", async () => { - const sig = await vkRegistryContract.genSubsidyVkSig( - stateTreeDepth, - treeDepths.intStateTreeDepth, - treeDepths.voteOptionTreeDepth, - ); - const vk = await vkRegistryContract.getSubsidyVkBySig(sig); - compareVks(testProcessVk, vk); - }); - }); }); }); diff --git a/contracts/ts/deploy.ts b/contracts/ts/deploy.ts index dbea0ff1f6..3edfdb5ca3 100644 --- a/contracts/ts/deploy.ts +++ b/contracts/ts/deploy.ts @@ -14,7 +14,6 @@ import { MockVerifier, PollFactory, MessageProcessorFactory, - SubsidyFactory, TallyFactory, PoseidonT3, PoseidonT4, @@ -283,14 +282,7 @@ export const deployMaci = async ({ poseidonT6, })); - const contractsToLink = [ - "MACI", - "PollFactory", - "MessageProcessorFactory", - "TallyFactory", - "TallyNonQvFactory", - "SubsidyFactory", - ]; + const contractsToLink = ["MACI", "PollFactory", "MessageProcessorFactory", "TallyFactory", "TallyNonQvFactory"]; // Link Poseidon contracts to MACI const linkedContractFactories = await Promise.all( @@ -307,14 +299,8 @@ export const deployMaci = async ({ ), ); - const [ - maciContractFactory, - pollFactoryContractFactory, - messageProcessorFactory, - tallyFactory, - tallyFactoryNonQv, - subsidyFactory, - ] = await Promise.all(linkedContractFactories); + const [maciContractFactory, pollFactoryContractFactory, messageProcessorFactory, tallyFactory, tallyFactoryNonQv] = + await Promise.all(linkedContractFactories); const pollFactoryContract = await deployContractWithLinkedLibraries( pollFactoryContractFactory, @@ -334,17 +320,10 @@ export const deployMaci = async ({ ? await deployContractWithLinkedLibraries(tallyFactory, "TallyFactory", quiet) : await deployContractWithLinkedLibraries(tallyFactoryNonQv, "TallyNonQvFactory", quiet); - const subsidyFactoryContract = await deployContractWithLinkedLibraries( - subsidyFactory, - "SubsidyFactory", - quiet, - ); - - const [pollAddr, mpAddr, tallyAddr, subsidyAddr] = await Promise.all([ + const [pollAddr, mpAddr, tallyAddr] = await Promise.all([ pollFactoryContract.getAddress(), messageProcessorFactoryContract.getAddress(), tallyFactoryContract.getAddress(), - subsidyFactoryContract.getAddress(), ]); const maciContract = await deployContractWithLinkedLibraries( @@ -354,7 +333,6 @@ export const deployMaci = async ({ pollAddr, mpAddr, tallyAddr, - subsidyAddr, signUpTokenGatekeeperContractAddress, initialVoiceCreditBalanceAddress, topupCreditContractAddress, diff --git a/contracts/ts/genMaciState.ts b/contracts/ts/genMaciState.ts index 371797ec28..6e93db0c78 100644 --- a/contracts/ts/genMaciState.ts +++ b/contracts/ts/genMaciState.ts @@ -174,7 +174,6 @@ export const genMaciStateFromContract = async ( }; const batchSizes = { tallyBatchSize: STATE_TREE_ARITY ** Number(onChainTreeDepths.intStateTreeDepth), - subsidyBatchSize: STATE_TREE_ARITY ** Number(onChainTreeDepths.intStateTreeDepth), messageBatchSize: STATE_TREE_ARITY ** Number(onChainTreeDepths.messageTreeSubDepth), }; diff --git a/core/ts/MaciState.ts b/core/ts/MaciState.ts index 25f7162e3a..62b9bbd7ec 100644 --- a/core/ts/MaciState.ts +++ b/core/ts/MaciState.ts @@ -75,7 +75,6 @@ export class MaciState implements IMaciState { treeDepths, { messageBatchSize, - subsidyBatchSize: STATE_TREE_ARITY ** treeDepths.intStateTreeDepth, tallyBatchSize: STATE_TREE_ARITY ** treeDepths.intStateTreeDepth, }, maxValues, diff --git a/core/ts/Poll.ts b/core/ts/Poll.ts index 6a3528d2ea..58a8fc251d 100644 --- a/core/ts/Poll.ts +++ b/core/ts/Poll.ts @@ -40,14 +40,13 @@ import type { IJsonPoll, IProcessMessagesOutput, ITallyCircuitInputs, - ISubsidyCircuitInputs, IProcessMessagesCircuitInputs, } from "./utils/types"; import type { PathElements } from "maci-crypto"; import { STATE_TREE_ARITY, MESSAGE_TREE_ARITY } from "./utils/constants"; import { ProcessMessageErrors, ProcessMessageError } from "./utils/errors"; -import { packTallyVotesSmallVals, packSubsidySmallVals } from "./utils/utils"; +import { packTallyVotesSmallVals } from "./utils/utils"; /** * A representation of the Poll contract. @@ -112,19 +111,6 @@ export class Poll implements IPoll { totalSpentVoiceCredits = 0n; - // For coefficient and subsidy calculation - subsidy: bigint[] = []; // size: M, M is number of vote options - - subsidySalts: Record = {}; - - rbi = 0; // row batch index - - cbi = 0; // column batch index - - MM = 50; // adjustable parameter - - WW = 4; // number of digits for float representation - // an empty ballot and its hash to be used as zero value in the // ballot tree emptyBallot: Ballot; @@ -169,7 +155,6 @@ export class Poll implements IPoll { this.tallyResult = new Array(this.maxValues.maxVoteOptions).fill(0n) as bigint[]; this.perVOSpentVoiceCredits = new Array(this.maxValues.maxVoteOptions).fill(0n) as bigint[]; - this.subsidy = new Array(this.maxValues.maxVoteOptions).fill(0n) as bigint[]; // we put a blank state leaf to prevent a DoS attack this.emptyBallot = Ballot.genBlankBallot(this.maxValues.maxVoteOptions, treeDepths.voteOptionTreeDepth); @@ -896,182 +881,6 @@ export class Poll implements IPoll { */ hasUntalliedBallots = (): boolean => this.numBatchesTallied * this.batchSizes.tallyBatchSize < this.ballots.length; - /** - * This method checks if there are any unfinished subsidy calculations. - * @returns Returns true if the product of the row batch index (rbi) and batch size or - * the product of column batch index (cbi) and batch size is less than the length - * of the ballots array, indicating that there are still ballots left to be processed. - * Otherwise, it returns false. - */ - hasUnfinishedSubsidyCalculation = (): boolean => { - const batchSize = this.batchSizes.subsidyBatchSize; - return this.rbi * batchSize < this.ballots.length && this.cbi * batchSize < this.ballots.length; - }; - - /** - * This method calculates the subsidy per batch. - * @returns Returns an array of big integers which represent the circuit inputs for the subsidy calculation. - */ - subsidyPerBatch = (): ISubsidyCircuitInputs => { - const batchSize = this.batchSizes.subsidyBatchSize; - - assert(this.hasUnfinishedSubsidyCalculation(), "No more subsidy batches to calculate"); - - const stateRoot = this.stateTree!.root; - const ballotRoot = this.ballotTree!.root; - const sbSalt = this.sbSalts[this.currentMessageBatchIndex!]; - const sbCommitment = hash3([stateRoot, ballotRoot, sbSalt]); - - const currentSubsidy = this.subsidy.map((x) => BigInt(x.toString())); - let currentSubsidyCommitment = 0n; - let currentSubsidySalt = 0n; - let saltIndex = this.previousSubsidyIndexToString(); - - if (this.rbi !== 0 || this.cbi !== 0) { - currentSubsidySalt = BigInt(this.subsidySalts[saltIndex]); - currentSubsidyCommitment = BigInt( - genTreeCommitment(this.subsidy, currentSubsidySalt, this.treeDepths.voteOptionTreeDepth).valueOf(), - ); - } - - const rowStartIndex = this.rbi * batchSize; - const colStartIndex = this.cbi * batchSize; - const [ballots1, ballots2] = this.subsidyCalculation(rowStartIndex, colStartIndex); - - const ballotSubrootProof1 = this.ballotTree?.genSubrootProof(rowStartIndex, rowStartIndex + batchSize); - const ballotSubrootProof2 = this.ballotTree?.genSubrootProof(colStartIndex, colStartIndex + batchSize); - - const newSubsidySalt = genRandomSalt(); - saltIndex = `${this.rbi.toString()}-${this.cbi.toString()}`; - this.subsidySalts[saltIndex] = newSubsidySalt; - const newSubsidyCommitment = genTreeCommitment(this.subsidy, newSubsidySalt, this.treeDepths.voteOptionTreeDepth); - - const packedVals = packSubsidySmallVals(this.rbi, this.cbi, Number(this.numSignups)); - - const inputHash = sha256Hash([packedVals, sbCommitment, currentSubsidyCommitment, newSubsidyCommitment]); - - const circuitInputs = stringifyBigInts({ - stateRoot, - ballotRoot, - sbSalt, - currentSubsidySalt, - newSubsidySalt, - sbCommitment, - currentSubsidyCommitment, - newSubsidyCommitment, - currentSubsidy, - packedVals, - inputHash, - ballots1: ballots1.map((x) => x.asCircuitInputs()), - ballots2: ballots2.map((x) => x.asCircuitInputs()), - votes1: ballots1.map((x) => x.votes), - votes2: ballots2.map((x) => x.votes), - ballotPathElements1: ballotSubrootProof1!.pathElements, - ballotPathElements2: ballotSubrootProof2!.pathElements, - }) as unknown as ISubsidyCircuitInputs; - - this.increaseSubsidyIndex(); - return circuitInputs; - }; - - /** - * It increases the index for the subsidy calculation. - */ - private increaseSubsidyIndex = (): void => { - const batchSize = this.batchSizes.subsidyBatchSize; - - if (this.cbi * batchSize + batchSize < this.ballots.length) { - this.cbi += 1; - } else { - this.rbi += 1; - this.cbi = this.rbi; - } - }; - - /** - * This method converts the previous subsidy index to a string. - * @returns Returns a string representation of the previous subsidy index. - * The string is in the format "rbi-cbi", where rbi and cbi are - * the previous row batch index and column batch index respectively. - */ - private previousSubsidyIndexToString = (): string => { - const batchSize = this.batchSizes.subsidyBatchSize; - const numBatches = Math.ceil(this.ballots.length / batchSize); - - let { cbi } = this; - let { rbi } = this; - - if (this.cbi === 0 && this.rbi === 0) { - return "0-0"; - } - - if (this.cbi > this.rbi) { - cbi -= 1; - } else { - rbi -= 1; - cbi = numBatches - 1; - } - - return `${rbi.toString()}-${cbi.toString()}`; - }; - - /** - * This method calculates the coefficient for a pair of ballots. - * @param rowBallot - The ballot in the row. - * @param colBallot - The ballot in the column. - * - * @returns Returns the calculated coefficient. - */ - private coefficientCalculation = (rowBallot: Ballot, colBallot: Ballot): bigint => { - let sum = 0n; - for (let p = 0; p < this.maxValues.maxVoteOptions; p += 1) { - sum += BigInt(rowBallot.votes[p].valueOf()) * colBallot.votes[p]; - } - const res = BigInt(this.MM * 10 ** this.WW) / (BigInt(this.MM) + BigInt(sum)); - return res; - }; - - /** - * This method calculates the subsidy for a batch of ballots. - * @param rowStartIndex - The starting index for the row ballots. - * @param colStartIndex - The starting index for the column ballots. - * @returns Returns a 2D array of ballots. The first array contains the row ballots and the second array contains the column ballots. - */ - private subsidyCalculation = (rowStartIndex: number, colStartIndex: number): Ballot[][] => { - const batchSize = this.batchSizes.subsidyBatchSize; - const ballots1: Ballot[] = []; - const ballots2: Ballot[] = []; - const emptyBallot = new Ballot(this.maxValues.maxVoteOptions, this.treeDepths.voteOptionTreeDepth); - - for (let i = 0; i < batchSize; i += 1) { - const row = rowStartIndex + i; - const col = colStartIndex + i; - const rowBallot = row < this.ballots.length ? this.ballots[row] : emptyBallot; - const colBallot = col < this.ballots.length ? this.ballots[col] : emptyBallot; - ballots1.push(rowBallot); - ballots2.push(colBallot); - } - for (let i = 0; i < batchSize; i += 1) { - for (let j = 0; j < batchSize; j += 1) { - const row = rowStartIndex + i; - const col = colStartIndex + j; - const rowBallot = row < this.ballots.length ? this.ballots[row] : emptyBallot; - const colBallot = col < this.ballots.length ? this.ballots[col] : emptyBallot; - - const kij = this.coefficientCalculation(rowBallot, colBallot); - for (let p = 0; p < this.maxValues.maxVoteOptions; p += 1) { - const vip = BigInt(rowBallot.votes[p].valueOf()); - const vjp = BigInt(colBallot.votes[p].valueOf()); - if (rowStartIndex !== colStartIndex || (rowStartIndex === colStartIndex && i < j)) { - this.subsidy[p] += 2n * kij * vip * vjp; - } - } - } - } - - return [ballots1, ballots2]; - }; - /** * This method tallies a ballots and updates the tally results. * @returns the circuit inputs for the TallyVotes circuit. @@ -1463,7 +1272,6 @@ export class Poll implements IPoll { }, { tallyBatchSize: Number(this.batchSizes.tallyBatchSize.toString()), - subsidyBatchSize: Number(this.batchSizes.subsidyBatchSize.toString()), messageBatchSize: Number(this.batchSizes.messageBatchSize.toString()), }, { @@ -1515,17 +1323,6 @@ export class Poll implements IPoll { copied.spentVoiceCreditSubtotalSalts[k] = BigInt(this.spentVoiceCreditSubtotalSalts[k].toString()); }); - // subsidy related copy - copied.subsidy = this.subsidy.map((x: bigint) => BigInt(x.toString())); - copied.rbi = Number(this.rbi.toString()); - copied.cbi = Number(this.cbi.toString()); - copied.MM = Number(this.MM.toString()); - copied.WW = Number(this.WW.toString()); - - Object.keys(this.subsidySalts).forEach((k) => { - copied.subsidySalts[k] = BigInt(this.subsidySalts[k].toString()); - }); - // update the number of signups copied.setNumSignups(this.numSignups); diff --git a/core/ts/__tests__/Poll.test.ts b/core/ts/__tests__/Poll.test.ts index 629b4783b5..dd0aad5a95 100644 --- a/core/ts/__tests__/Poll.test.ts +++ b/core/ts/__tests__/Poll.test.ts @@ -541,65 +541,6 @@ describe("Poll", function test() { }); }); - describe("subsidy", () => { - const maciState = new MaciState(STATE_TREE_DEPTH); - const pollId = maciState.deployPoll( - BigInt(Math.floor(Date.now() / 1000) + duration), - maxValues, - treeDepths, - messageBatchSize, - coordinatorKeypair, - ); - - const poll = maciState.polls.get(pollId)!; - - const user1Keypair = new Keypair(); - // signup the user - const user1StateIndex = maciState.signUp( - user1Keypair.pubKey, - voiceCreditBalance, - BigInt(Math.floor(Date.now() / 1000)), - ); - - const voteWeight = 5n; - const voteOption = 0n; - - const command = new PCommand( - BigInt(user1StateIndex), - user1Keypair.pubKey, - voteOption, - voteWeight, - 1n, - BigInt(pollId), - ); - - const signature = command.sign(user1Keypair.privKey); - - const ecdhKeypair = new Keypair(); - const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); - - const message = command.encrypt(signature, sharedKey); - - before(() => { - poll.updatePoll(BigInt(maciState.stateLeaves.length)); - poll.publishMessage(message, ecdhKeypair.pubKey); - poll.processAllMessages(); - poll.tallyVotes(); - }); - - it("should calculate the subsidy", () => { - const { rbi, cbi } = poll; - expect(() => poll.subsidyPerBatch()).to.not.throw(); - const { rbi: newRbi, cbi: newCbi } = poll; - expect(newRbi).to.eq(rbi + 1); - expect(newCbi).to.eq(cbi + 1); - }); - - it("should throw when the subsidy was already calculated", () => { - expect(() => poll.subsidyPerBatch()).to.throw("No more subsidy batches to calculate"); - }); - }); - describe("setCoordinatorKeypair", () => { it("should update the coordinator's Keypair", () => { const maciState = new MaciState(STATE_TREE_DEPTH); diff --git a/core/ts/__tests__/utils.test.ts b/core/ts/__tests__/utils.test.ts index 4e49e292a0..964aa897e1 100644 --- a/core/ts/__tests__/utils.test.ts +++ b/core/ts/__tests__/utils.test.ts @@ -3,12 +3,10 @@ import { expect } from "chai"; import { genProcessVkSig, genTallyVkSig, - genSubsidyVkSig, packProcessMessageSmallVals, unpackProcessMessageSmallVals, packTallyVotesSmallVals, unpackTallyVotesSmallVals, - packSubsidySmallVals, } from "../utils/utils"; describe("Utils", () => { @@ -22,11 +20,6 @@ describe("Utils", () => { expect(result).to.equal(340282366920938463500268095579187314691n); }); - it("genSubsidyVkSig should work", () => { - const result = genSubsidyVkSig(1, 2, 3); - expect(result).to.equal(340282366920938463500268095579187314691n); - }); - it("packProcessMessageSmallVals should work", () => { const result = packProcessMessageSmallVals(1n, 2n, 3, 4); expect(result).to.equal(5708990770823843327184944562488436835454287873n); @@ -54,9 +47,4 @@ describe("Utils", () => { batchStartIndex: 0n, }); }); - - it("packSubsidySmallVals should work", () => { - const result = packSubsidySmallVals(1, 2, 3); - expect(result).to.equal(3802951800684689330390016458754n); - }); }); diff --git a/core/ts/index.ts b/core/ts/index.ts index 9f756d42c8..0df07c8154 100644 --- a/core/ts/index.ts +++ b/core/ts/index.ts @@ -5,18 +5,15 @@ export { Poll } from "./Poll"; export { genProcessVkSig, genTallyVkSig, - genSubsidyVkSig, packProcessMessageSmallVals, unpackProcessMessageSmallVals, packTallyVotesSmallVals, unpackTallyVotesSmallVals, - packSubsidySmallVals, } from "./utils/utils"; export type { ITallyCircuitInputs, IProcessMessagesCircuitInputs, - ISubsidyCircuitInputs, CircuitInputs, MaxValues, TreeDepths, diff --git a/core/ts/utils/types.ts b/core/ts/utils/types.ts index d02abe7e3c..df483ead42 100644 --- a/core/ts/utils/types.ts +++ b/core/ts/utils/types.ts @@ -39,12 +39,10 @@ export interface TreeDepths { * This interface defines the batch sizes. * @property tallyBatchSize - The size of the tally batch. * @property messageBatchSize - The size of the message batch. - * @property subsidyBatchSize - The size of the subsidy batch. */ export interface BatchSizes { tallyBatchSize: number; messageBatchSize: number; - subsidyBatchSize: number; } /** @@ -92,8 +90,6 @@ export interface IPoll { hasUnprocessedMessages(): boolean; processAllMessages(): { stateLeaves: StateLeaf[]; ballots: Ballot[] }; hasUntalliedBallots(): boolean; - hasUnfinishedSubsidyCalculation(): boolean; - subsidyPerBatch(): ISubsidyCircuitInputs; copy(): Poll; equals(p: Poll): boolean; toJSON(): IJsonPoll; @@ -199,26 +195,3 @@ export interface ITallyCircuitInputs { newPerVOSpentVoiceCreditsRootSalt?: string; newSpentVoiceCreditSubtotalSalt: string; } - -/** - * An interface describing the circuit inputs to the Subsidy circuit - */ -export interface ISubsidyCircuitInputs { - stateRoot: string; - ballotRoot: string; - sbSalt: string; - currentSubsidySalt: string; - newSubsidySalt: string; - sbCommitment: string; - currentSubsidyCommitment: string; - newSubsidyCommitment: string; - currentSubsidy: string[]; - packedVals: string; - inputHash: string; - ballots1: string[]; - ballots2: string[]; - votes1: number[]; - votes2: number[]; - ballotPathElements1: string[]; - ballotPathElements2: string[]; -} diff --git a/core/ts/utils/utils.ts b/core/ts/utils/utils.ts index 38374ef262..14b1622eb4 100644 --- a/core/ts/utils/utils.ts +++ b/core/ts/utils/utils.ts @@ -38,22 +38,6 @@ export const genTallyVkSig = ( _voteOptionTreeDepth: number, ): bigint => (BigInt(_stateTreeDepth) << 128n) + (BigInt(_intStateTreeDepth) << 64n) + BigInt(_voteOptionTreeDepth); -/** - * This function generates the signature of a Subsidy Verifying Key(VK). - * This can be used to check if a SubsidyCalculations' circuit VK is registered - * in a smart contract that holds several VKs. - * @param _stateTreeDepth - The depth of the state tree. - * @param _intStateTreeDepth - The depth of the intermediate state tree. - * @param _voteOptionTreeDepth - The depth of the vote option tree. - * @returns Returns a signature for querying if a verifying key with - * the given parameters is already registered in the contract. - */ -export const genSubsidyVkSig = ( - _stateTreeDepth: number, - _intStateTreeDepth: number, - _voteOptionTreeDepth: number, -): bigint => (BigInt(_stateTreeDepth) << 128n) + (BigInt(_intStateTreeDepth) << 64n) + BigInt(_voteOptionTreeDepth); - /** * This function packs it's parameters into a single bigint. * @param maxVoteOptions - The maximum number of vote options. @@ -139,17 +123,3 @@ export const unpackTallyVotesSmallVals = (packedVals: bigint): { numSignUps: big return { numSignUps, batchStartIndex }; }; - -/** - * This function packs it's parameters into a single bigint. - * @param row - The row. - * @param col - The column. - * @param numSignUps - The number of signups. - * @returns Returns a single bigint that contains the packed values. - */ -export const packSubsidySmallVals = (row: number, col: number, numSignUps: number): bigint => { - // Note: the << operator has lower precedence than + - const packedVals = (BigInt(numSignUps) << 100n) + (BigInt(row) << 50n) + BigInt(col); - - return packedVals; -}; diff --git a/integrationTests/ts/__tests__/data/suites.json b/integrationTests/ts/__tests__/data/suites.json index a8d161db97..e76f98ba8e 100644 --- a/integrationTests/ts/__tests__/data/suites.json +++ b/integrationTests/ts/__tests__/data/suites.json @@ -108,8 +108,8 @@ "expectedTotalSpentVoiceCredits": 8 }, { - "name": "Subsidy test", - "description": "has subsidy result", + "name": "4 users 1 vote each", + "description": "4 users 1 vote each", "numUsers": 4, "numVotesPerUser": 1, "votes": { @@ -128,11 +128,7 @@ }, "expectedTally": [4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "expectedSpentVoiceCredits": [4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - "expectedTotalSpentVoiceCredits": 4, - "subsidy": { - "enabled": true, - "expectedSubsidy": [117636, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] - } + "expectedTotalSpentVoiceCredits": 4 } ] } diff --git a/integrationTests/ts/__tests__/integration.test.ts b/integrationTests/ts/__tests__/integration.test.ts index 0e9b4d854d..d9a545e2c7 100644 --- a/integrationTests/ts/__tests__/integration.test.ts +++ b/integrationTests/ts/__tests__/integration.test.ts @@ -17,7 +17,6 @@ import { verify, DeployedContracts, PollContracts, - SubsidyData, } from "maci-cli"; import { getDefaultSigner } from "maci-contracts"; import { MaciState, MaxValues, TreeDepths } from "maci-core"; @@ -41,8 +40,8 @@ import { maxMessages, messageBatchDepth, } from "./utils/constants"; -import { ITestSuite, Subsidy } from "./utils/interfaces"; -import { expectSubsidy, expectTally, genTestUserCommands, isArm } from "./utils/utils"; +import { ITestSuite } from "./utils/interfaces"; +import { expectTally, genTestUserCommands, isArm } from "./utils/utils"; chai.use(chaiAsPromised); @@ -88,10 +87,6 @@ describe("Integration tests", function test() { "../../../cli/zkeys/TallyVotes_10-1-2_test/TallyVotes_10-1-2_test.0.zkey", ), vkRegistry: vkRegistryAddress, - subsidyZkeyPath: path.resolve( - __dirname, - "../../../cli/zkeys/SubsidyPerBatch_10-1-2_test/SubsidyPerBatch_10-1-2_test.0.zkey", - ), signer, }); }); @@ -117,7 +112,6 @@ describe("Integration tests", function test() { messageTreeDepth: MSG_TREE_DEPTH, voteOptionTreeDepth: VOTE_OPTION_TREE_DEPTH, coordinatorPubkey: coordinatorKeypair.pubKey.serialize(), - subsidyEnabled: true, maciAddress: contracts.maciAddress, signer, }); @@ -146,10 +140,6 @@ describe("Integration tests", function test() { fs.unlinkSync(path.resolve(__dirname, "../../../cli/tally.json")); } - if (fs.existsSync(path.resolve(__dirname, "../../../cli/subsidy.json"))) { - fs.unlinkSync(path.resolve(__dirname, "../../../cli/subsidy.json")); - } - const directory = path.resolve(__dirname, "../../../cli/proofs/"); if (!fs.existsSync(directory)) { @@ -174,9 +164,6 @@ describe("Integration tests", function test() { data.suites.forEach((testCase) => { it(testCase.description, async () => { - // check if we have subsidy enabled - const subsidyEnabled = Boolean(testCase.subsidy?.enabled); - const users = genTestUserCommands(testCase.numUsers, testCase.numVotesPerUser, testCase.bribers, testCase.votes); // loop through all users and generate keypair + signup @@ -270,11 +257,6 @@ describe("Integration tests", function test() { "../../../cli/zkeys/ProcessMessages_10-2-1-2_test/ProcessMessages_10-2-1-2_test.0.zkey", ), pollId, - subsidyFile: path.resolve(__dirname, "../../../cli/subsidy.json"), - subsidyZkey: path.resolve( - __dirname, - "../../../cli/zkeys/SubsidyPerBatch_10-1-2_test/SubsidyPerBatch_10-1-2_test.0.zkey", - ), rapidsnark: `${homedir()}/rapidsnark/build/prover`, processWitgen: path.resolve( __dirname, @@ -292,14 +274,6 @@ describe("Integration tests", function test() { __dirname, "../../../cli/zkeys/TallyVotes_10-1-2_test/TallyVotes_10-1-2_test_cpp/TallyVotes_10-1-2_test.dat", ), - subsidyWitgen: path.resolve( - __dirname, - "../../../cli/zkeys/SubsidyPerBatch_10-1-2_test/SubsidyPerBatch_10-1-2_test_cpp/SubsidyPerBatch_10-1-2_test", - ), - subsidyDatFile: path.resolve( - __dirname, - "../../../cli/zkeys/SubsidyPerBatch_10-1-2_test/SubsidyPerBatch_10-1-2_test_cpp/SubsidyPerBatch_10-1-2_test.dat", - ), coordinatorPrivKey: coordinatorKeypair.privKey.serialize(), maciAddress: contracts.maciAddress, processWasm: path.resolve( @@ -310,10 +284,6 @@ describe("Integration tests", function test() { __dirname, "../../../cli/zkeys/TallyVotes_10-1-2_test/TallyVotes_10-1-2_test_js/TallyVotes_10-1-2_test.wasm", ), - subsidyWasm: path.resolve( - __dirname, - "../../../cli/zkeys/SubsidyPerBatch_10-1-2_test/SubsidyPerBatch_10-1-2_test_js/SubsidyPerBatch_10-1-2_test.wasm", - ), useWasm, signer, }); @@ -328,23 +298,14 @@ describe("Integration tests", function test() { tallyData, ); - if (subsidyEnabled) { - const subsidy = JSON.parse( - fs.readFileSync(path.resolve(__dirname, "../../../cli/subsidy.json")).toString(), - ) as Subsidy; - expectSubsidy(maxMessages, testCase.subsidy?.expectedSubsidy ?? [], subsidy); - } - // prove on chain if everything matches await expect( proveOnChain({ pollId, proofDir: path.resolve(__dirname, "../../../cli/proofs"), - subsidyEnabled, maciAddress: contracts.maciAddress, messageProcessorAddress: pollContracts.messageProcessor, tallyAddress: pollContracts.tally, - subsidyAddress: pollContracts.subsidy, signer, }), ).to.not.be.rejected; @@ -353,16 +314,9 @@ describe("Integration tests", function test() { await expect( verify({ pollId, - subsidyEnabled, tallyData, maciAddress: contracts.maciAddress, tallyAddress: pollContracts.tally, - subsidyAddress: pollContracts.subsidy, - subsidyData: subsidyEnabled - ? (JSON.parse( - fs.readFileSync(path.resolve(__dirname, "../../../cli/subsidy.json")).toString(), - ) as SubsidyData) - : undefined, signer, }), ).to.not.be.rejected; diff --git a/integrationTests/ts/__tests__/maci-keys.test.ts b/integrationTests/ts/__tests__/maci-keys.test.ts index 2f21357cb4..5a27381609 100644 --- a/integrationTests/ts/__tests__/maci-keys.test.ts +++ b/integrationTests/ts/__tests__/maci-keys.test.ts @@ -92,7 +92,6 @@ describe("integration tests private/public/keypair", () => { coordinatorKeypair.pubKey.asContractParam(), verifier, vkRegistry, - false, ); // we know it's the first poll so id is 0 diff --git a/integrationTests/ts/__tests__/utils/interfaces.ts b/integrationTests/ts/__tests__/utils/interfaces.ts index acab3e0266..9bfd6297ce 100644 --- a/integrationTests/ts/__tests__/utils/interfaces.ts +++ b/integrationTests/ts/__tests__/utils/interfaces.ts @@ -24,20 +24,6 @@ export interface IChangeUsersKeys { voteWeight: bigint; } -/** - * A util interface that represents a subsidy file - */ -export interface Subsidy { - provider: string; - maci: string; - pollId: number; - newSubsidyCommitment: string; - results: { - subsidy: string[]; - salt: string; - }; -} - /** * A util interface that represents a test suite */ @@ -49,7 +35,6 @@ export interface ITestSuite { expectedTally: number[]; expectedSpentVoiceCredits: number[]; expectedTotalSpentVoiceCredits: number; - subsidy?: { enabled: boolean; expectedSubsidy: number[] }; bribers?: IBriber[]; votes?: IVote[][]; changeUsersKeys?: IChangeUsersKeys[][]; diff --git a/integrationTests/ts/__tests__/utils/utils.ts b/integrationTests/ts/__tests__/utils/utils.ts index 1623114362..82a16ba13c 100644 --- a/integrationTests/ts/__tests__/utils/utils.ts +++ b/integrationTests/ts/__tests__/utils/utils.ts @@ -18,7 +18,7 @@ import { arch } from "os"; import type { TallyData } from "maci-cli"; import { defaultVote } from "./constants"; -import { Subsidy, IVote, IBriber, IDeployedTestContracts } from "./interfaces"; +import { IVote, IBriber, IDeployedTestContracts } from "./interfaces"; import { UserCommand } from "./user"; /** @@ -140,24 +140,6 @@ export const expectTally = ( expect(tallyFile.totalSpentVoiceCredits.spent).to.eq(expectedTotalSpentVoiceCredits.toString()); }; -/** - * Assertion function to ensure that the subsidy results are as expected - * @param maxMessages - the max number of messages - * @param expectedSubsidy - the expected subsidy values - * @param SubsidyFile - the subsidy file itself as an object - */ -export const expectSubsidy = (maxMessages: number, expectedSubsidy: number[], subsidyFile: Subsidy): void => { - const genSubsidy = Array(maxMessages).fill("0"); - - expectedSubsidy.forEach((value, index) => { - if (value !== 0) { - genSubsidy[index] = value.toString(); - } - }); - - expect(subsidyFile.results.subsidy).to.deep.equal(genSubsidy); -}; - /** * Stop the current thread for x seconds * @param ms - the number of ms to sleep for