diff --git a/.github/scripts/ceremony-param-tests-c-witness.sh b/.github/scripts/ceremony-param-tests-c-witness.sh deleted file mode 100755 index b4e7fc9ef5..0000000000 --- a/.github/scripts/ceremony-param-tests-c-witness.sh +++ /dev/null @@ -1,74 +0,0 @@ -#!/bin/bash - -set -e - -cd "$(dirname "$0")" -cd ../../cli - -HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js deployVkRegistry -q true -HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js setVerifyingKeys \ - --state-tree-depth 6 \ - --int-state-tree-depth 2 \ - --msg-tree-depth 8 \ - --vote-option-tree-depth 3 \ - --msg-batch-depth 2 \ - --process-messages-zkey ./zkeys/processMessages_6-8-2-3.zkey \ - --tally-votes-zkey ./zkeys/tallyVotes_6-2-3.zkey \ - -q true -HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js create -s 6 -q true -HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js deployPoll \ - -pk macipk.ea638a3366ed91f2e955110888573861f7c0fc0bb5fb8b8dca9cd7a08d7d6b93 \ - --duration 300 \ - --max-messages 390625 \ - --max-vote-options 125 \ - --int-state-tree-depth 2 \ - --msg-tree-depth 8 \ - --msg-batch-depth 2 \ - --vote-option-tree-depth 3 \ - --subsidy-enabled false \ - -q true -HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js signup \ - --pubkey macipk.e743ffb5298ef0f5c1f63b6464a48fea19ea7ee5a885c67ae1b24a1d04f03f07 \ - -q true -HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js publish \ - --pubkey macipk.e743ffb5298ef0f5c1f63b6464a48fea19ea7ee5a885c67ae1b24a1d04f03f07 \ - --privkey macisk.0ab0281365e01cff60afc62310daec765e590487bf989a7c4986ebc3fd49895e \ - --state-index 1 \ - --vote-option-index 0 \ - --new-vote-weight 9 \ - --nonce 1 \ - --poll-id 0 \ - -q true -HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js publish \ - --pubkey macipk.e743ffb5298ef0f5c1f63b6464a48fea19ea7ee5a885c67ae1b24a1d04f03f07 \ - --privkey macisk.0ab0281365e01cff60afc62310daec765e590487bf989a7c4986ebc3fd49895e \ - --state-index 1 \ - --vote-option-index 1 \ - --new-vote-weight 9 \ - --nonce 2 \ - --poll-id 0 \ - -q true -HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js timeTravel -s 300 -q true -HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js mergeSignups --poll-id 0 -q true -HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js mergeMessages --poll-id 0 -q true -HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js genProofs \ - --privkey macisk.1751146b59d32e3c0d7426de411218172428263f93b2fc4d981c036047a4d8c0 \ - --poll-id 0 \ - --rapidsnark ~/rapidsnark/build/prover \ - --process-zkey ./zkeys/processMessages_6-8-2-3.zkey \ - --tally-zkey ./zkeys/tallyVotes_6-2-3.zkey \ - --tally-file tally.json \ - --output proofs/ \ - --tally-witnessgen ./zkeys/tallyVotes_6-2-3 \ - --process-witnessgen ./zkeys/processMessages_6-8-2-3 \ - -q true -HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js proveOnChain \ - --poll-id 0 \ - --proof-dir proofs/ \ - --subsidy-enabled false \ - -q true -HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js verify \ - --poll-id 0 \ - --subsidy-enabled false \ - --tally-file tally.json \ - -q true diff --git a/.github/workflows/nightly-ceremony.yml b/.github/workflows/nightly-ceremony.yml index 3e5267d246..454ee3a452 100644 --- a/.github/workflows/nightly-ceremony.yml +++ b/.github/workflows/nightly-ceremony.yml @@ -1,20 +1,54 @@ name: Nightly Ceremony on: - schedule: - - cron: 0 0 * * * + push: + branches: + - test/stress-test env: STATE_TREE_DEPTH: ${{ vars.STATE_TREE_DEPTH }} jobs: + start-runner: + name: Start self-hosted EC2 runner + runs-on: ubuntu-latest + outputs: + label: ${{ steps.start-ec2-runner.outputs.label }} + ec2-instance-id: ${{ steps.start-ec2-runner.outputs.ec2-instance-id }} + steps: + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v2 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: ${{ secrets.AWS_REGION }} + + - name: Start EC2 runner + id: start-ec2-runner + uses: machulav/ec2-github-runner@v2 + with: + mode: start + github-token: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }} + ec2-image-id: ami-04950f0be945cc4c7 + ec2-instance-type: t3.2xlarge + subnet-id: subnet-0817be1b2160793b5 + security-group-id: sg-0aea3cbb15e30a921 + aws-resource-tags: > + [ + { "Key": "Name", "Value": "maci-github-runner" }, + { "Key": "GitHubRepository", "Value": "${{ github.repository }}" } + ] + test-with-ceremony-keys: - runs-on: ubuntu-22.04 + # required to start the main job when the runner is ready + needs: start-runner + # run the job on the newly created runner + runs-on: ${{ needs.start-runner.outputs.label }} steps: - uses: actions/checkout@v4 with: - ref: dev + ref: test/stress-test - uses: pnpm/action-setup@v2 with: version: latest @@ -57,9 +91,33 @@ jobs: - name: Download ceremony artifacts run: ./.github/scripts/download-ceremony-artifacts.sh - - name: Run e2e tests - run: ./.github/scripts/ceremony-param-tests-c-witness.sh + - name: Run stress tests + run: pnpm run test:stress - name: Stop Hardhat if: always() run: kill $(lsof -t -i:8545) + + stop-runner: + name: Stop self-hosted EC2 runner + needs: + - start-runner # required to get output from the start-runner job + - test-with-ceremony-keys # required to wait when the main job is done + runs-on: ubuntu-latest + # required to stop the runner even if the error happened in the previous jobs + if: ${{ always() }} + steps: + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v2 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: ${{ secrets.AWS_REGION }} + + - name: Stop EC2 runner + uses: machulav/ec2-github-runner@v2 + with: + mode: stop + github-token: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }} + label: ${{ needs.start-runner.outputs.label }} + ec2-instance-id: ${{ needs.start-runner.outputs.ec2-instance-id }} diff --git a/.github/workflows/reusable-e2e.yml b/.github/workflows/reusable-e2e.yml index 86d4da6a3f..6947a7039e 100644 --- a/.github/workflows/reusable-e2e.yml +++ b/.github/workflows/reusable-e2e.yml @@ -10,6 +10,7 @@ jobs: matrix: command: ["test:cli", "test:integration"] + timeout-minutes: 240 runs-on: ubuntu-22.04 steps: diff --git a/circuits/scripts/build_intel.sh b/circuits/scripts/build_intel.sh index a6fb9b79ce..d94ff3b421 100644 --- a/circuits/scripts/build_intel.sh +++ b/circuits/scripts/build_intel.sh @@ -18,4 +18,4 @@ do make cd "$CWD" -done \ No newline at end of file +done diff --git a/cli/package.json b/cli/package.json index 57982819f8..fb4749c55a 100644 --- a/cli/package.json +++ b/cli/package.json @@ -14,17 +14,18 @@ "build": "tsc -p tsconfig.build.json", "postbuild": "cp package.json ./build", "types": "tsc -p tsconfig.json --noEmit", - "test": "nyc ts-mocha --exit tests/**/*.test.ts", - "test:e2e": "ts-mocha --exit tests/e2e/e2e.test.ts", - "test:e2e-subsidy": "ts-mocha --exit tests/e2e/e2e.subsidy.test.ts", - "test:keyChange": "ts-mocha --exit tests/e2e/keyChange.test.ts", + "test": "nyc ts-mocha --exit tests/e2e/*.test.ts tests/unit/*.test.ts", + "test:e2e": "ts-mocha --exit tests/e2e.test.ts", + "test:e2e-subsidy": "ts-mocha --exit tests/e2e.subsidy.test.ts", + "test:keyChange": "ts-mocha --exit tests/keyChange.test.ts", "test:unit": "nyc ts-mocha --exit tests/unit/*.test.ts", "test:airdrop": "nyc ts-mocha --exit tests/unit/airdrop.test.ts", "test:genPubKey": "ts-mocha --exit tests/unit/genPubKey.test.ts", "test:genKeypair": "ts-mocha --exit tests/unit/genKeyPair.test.ts", "test:timeTravel": "ts-mocha --exit tests/unit/timeTravel.test.ts", "test:fundWallet": "ts-mocha --exit tests/unit/fundWallet.test.ts", - "test:utils": "ts-mocha --exit tests/unit/utils.test.ts" + "test:utils": "ts-mocha --exit tests/unit/utils.test.ts", + "test:stress": "ts-mocha --exit tests/stress/*.test.ts" }, "dependencies": { "@commander-js/extra-typings": "^11.1.0", diff --git a/cli/tests/constants.ts b/cli/tests/constants.ts index 7834b8a5c6..2fcfe23451 100644 --- a/cli/tests/constants.ts +++ b/cli/tests/constants.ts @@ -2,14 +2,22 @@ import { Keypair } from "maci-domainobjs"; import { homedir } from "os"; +// config params export const STATE_TREE_DEPTH = 10; export const INT_STATE_TREE_DEPTH = 1; export const MSG_TREE_DEPTH = 2; export const VOTE_OPTION_TREE_DEPTH = 2; export const MSG_BATCH_DEPTH = 1; +export const pollDuration = 90; +export const maxMessages = 25; +export const maxVoteOptions = 25; + +// coordinator keypair const coordinatorKeypair = new Keypair(); export const coordinatorPubKey = coordinatorKeypair.pubKey.serialize(); export const coordinatorPrivKey = coordinatorKeypair.privKey.serialize(); + +// local paths to zkeys, wasm, and witnesses export const processMessageTestZkeyPath = "./zkeys/ProcessMessages_10-2-1-2_test.0.zkey"; export const tallyVotesTestZkeyPath = "./zkeys/TallyVotes_10-1-2_test.0.zkey"; export const subsidyTestZkeyPath = "./zkeys/SubsidyPerBatch_10-1-2_test.0.zkey"; @@ -24,6 +32,9 @@ export const testProcessMessagesWasmPath = export const testTallyVotesWasmPath = "./zkeys/TallyVotes_10-1-2_test_js/TallyVotes_10-1-2_test.wasm"; export const testSubsidyWasmPath = "./zkeys/SubsidyPerBatch_10-1-2_test_js/SubsidyPerBatch_10-1-2_test.wasm"; export const testRapidsnarkPath = `${homedir()}/rapidsnark/build/prover`; -export const pollDuration = 90; -export const maxMessages = 25; -export const maxVoteOptions = 25; +export const ceremonyProcessMessageZkeyPath = "./zkeys/processMessages_6-8-2-3.zkey"; +export const ceremonyTallyVotesZkeyPath = "./zkeys/tallyVotes_6-2-3.zkey"; +export const cermeonyProcessMessagesWitnessPath = "./zkeys/processMessages_6-8-2-3"; +export const ceremonyTallyVotesWitnessPath = "./zkeys/tallyVotes_6-2-3"; +export const ceremonyProcessMessagesWasmPath = "./zkeys/processMessages_6-8-2-3.wasm"; +export const ceremonyTallyVotesWasmPath = "./zkeys/tallyVotes_6-2-3.wasm"; diff --git a/cli/tests/stress/stress.test.ts b/cli/tests/stress/stress.test.ts new file mode 100644 index 0000000000..925bf53f8f --- /dev/null +++ b/cli/tests/stress/stress.test.ts @@ -0,0 +1,436 @@ +import { genRandomSalt } from "maci-crypto"; +import { Keypair } from "maci-domainobjs"; + +import { + deploy, + deployPoll, + deployVkRegistryContract, + genProofs, + mergeMessages, + mergeSignups, + proveOnChain, + publish, + setVerifyingKeys, + signup, + timeTravel, + verify, +} from "../../ts/commands"; +import { DeployedContracts, PollContracts } from "../../ts/utils"; +import { + coordinatorPrivKey, + coordinatorPubKey, + ceremonyProcessMessageZkeyPath, + ceremonyTallyVotesZkeyPath, + ceremonyProcessMessagesWasmPath, + cermeonyProcessMessagesWitnessPath, + testProofsDirPath, + testRapidsnarkPath, + testTallyFilePath, + ceremonyTallyVotesWasmPath, + ceremonyTallyVotesWitnessPath, +} from "../constants"; +import { cleanVanilla, isArm } from "../utils"; + +describe("stress tests", function test() { + const messageTreeDepth = 8; + const stateTreeDepth = 6; + const voteOptionTreeDepth = 3; + const messageBatchDepth = 2; + const intStateTreeDepth = 2; + const maxVoteOptions = 5 ** voteOptionTreeDepth; + + const maxMessages = 5 ** messageTreeDepth; + const pollDuration = 60000; + + const subsidyEnabled = false; + + const useWasm = isArm(); + this.timeout(90000000); + + let maciAddresses: DeployedContracts; + let pollAddresses: PollContracts; + + // before all tests we deploy the vk registry contract and set the verifying keys + before(async () => { + // we deploy the vk registry contract + await deployVkRegistryContract(true); + // we set the verifying keys + await setVerifyingKeys( + stateTreeDepth, + intStateTreeDepth, + messageTreeDepth, + voteOptionTreeDepth, + messageBatchDepth, + ceremonyProcessMessageZkeyPath, + ceremonyTallyVotesZkeyPath, + ); + }); + + const users = Array(100).fill(new Keypair()); + + describe("1 user, 2 messages", () => { + after(() => { + cleanVanilla(); + }); + + before(async () => { + // deploy the smart contracts + maciAddresses = await deploy(stateTreeDepth); + // deploy a poll contract + pollAddresses = await deployPoll( + pollDuration, + maxMessages, + maxVoteOptions, + intStateTreeDepth, + messageBatchDepth, + messageTreeDepth, + voteOptionTreeDepth, + coordinatorPubKey, + subsidyEnabled, + ); + }); + + it("should signup 1 user", async () => { + await signup(users[0].pubKey.serialize()); + }); + + it("should publish 2 messages", async () => { + // eslint-disable-next-line @typescript-eslint/prefer-for-of + for (let i = 0; i < 2; i += 1) { + const randomVoteOption = Math.floor(Math.random() * 126); + const randomVoteWeight = Math.floor(Math.random() * 10); + // eslint-disable-next-line no-await-in-loop + await publish( + users[0].pubKey.serialize(), + i + 1, + randomVoteOption, + 1, + 0, + randomVoteWeight, + maciAddresses.maciAddress, + genRandomSalt().toString(), + users[0].privKey.serialize(), + ); + } + }); + + it("should generate zk-SNARK proofs and verify them", async () => { + await timeTravel(pollDuration); + await mergeMessages(0, maciAddresses.maciAddress); + await mergeSignups(0, maciAddresses.maciAddress); + const tallyFileData = await genProofs( + testProofsDirPath, + testTallyFilePath, + ceremonyTallyVotesZkeyPath, + ceremonyProcessMessageZkeyPath, + 0, + undefined, + undefined, + testRapidsnarkPath, + cermeonyProcessMessagesWitnessPath, + ceremonyTallyVotesWitnessPath, + undefined, + coordinatorPrivKey, + maciAddresses.maciAddress, + undefined, + ceremonyProcessMessagesWasmPath, + ceremonyTallyVotesWasmPath, + undefined, + useWasm, + undefined, + undefined, + undefined, + undefined, + 300, + ); + await proveOnChain("0", testProofsDirPath, subsidyEnabled); + await verify( + "0", + subsidyEnabled, + testTallyFilePath, + tallyFileData, + maciAddresses.maciAddress, + pollAddresses.tally, + ); + }); + }); + + describe("100 signups, 100 messages", () => { + after(() => { + cleanVanilla(); + }); + + before(async () => { + // deploy the smart contracts + maciAddresses = await deploy(stateTreeDepth); + // deploy a poll contract + pollAddresses = await deployPoll( + pollDuration, + maxMessages, + maxVoteOptions, + intStateTreeDepth, + messageBatchDepth, + messageTreeDepth, + voteOptionTreeDepth, + coordinatorPubKey, + subsidyEnabled, + ); + }); + + it("should signup 100 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(users[i].pubKey.serialize()); + } + }); + + it("should publish 100 messages", async () => { + // eslint-disable-next-line @typescript-eslint/prefer-for-of + for (let i = 0; i < users.length; i += 1) { + const randomVoteOption = Math.floor(Math.random() * 126); + const randomVoteWeight = Math.floor(Math.random() * 10); + // eslint-disable-next-line no-await-in-loop + await publish( + users[i].pubKey.serialize(), + i + 1, + randomVoteOption, + 1, + 0, + randomVoteWeight, + maciAddresses.maciAddress, + genRandomSalt().toString(), + users[i].privKey.serialize(), + ); + } + }); + + it("should generate zk-SNARK proofs and verify them", async () => { + await timeTravel(pollDuration); + await mergeMessages(0, maciAddresses.maciAddress); + await mergeSignups(0, maciAddresses.maciAddress); + const tallyFileData = await genProofs( + testProofsDirPath, + testTallyFilePath, + ceremonyTallyVotesZkeyPath, + ceremonyProcessMessageZkeyPath, + 0, + undefined, + undefined, + testRapidsnarkPath, + cermeonyProcessMessagesWitnessPath, + ceremonyTallyVotesWitnessPath, + undefined, + coordinatorPrivKey, + maciAddresses.maciAddress, + undefined, + ceremonyProcessMessagesWasmPath, + ceremonyTallyVotesWasmPath, + undefined, + useWasm, + undefined, + undefined, + undefined, + undefined, + 300, + ); + await proveOnChain("0", testProofsDirPath, subsidyEnabled); + await verify( + "0", + subsidyEnabled, + testTallyFilePath, + tallyFileData, + maciAddresses.maciAddress, + pollAddresses.tally, + ); + }); + }); + + describe("50 signups, 200 messages", () => { + after(() => { + cleanVanilla(); + }); + + before(async () => { + // deploy the smart contracts + maciAddresses = await deploy(stateTreeDepth); + // deploy a poll contract + pollAddresses = await deployPoll( + pollDuration, + maxMessages, + maxVoteOptions, + intStateTreeDepth, + messageBatchDepth, + messageTreeDepth, + voteOptionTreeDepth, + coordinatorPubKey, + subsidyEnabled, + ); + }); + + it("should signup 50 users", async () => { + // eslint-disable-next-line @typescript-eslint/prefer-for-of + for (let i = 0; i < 50; i += 1) { + // eslint-disable-next-line no-await-in-loop + await signup(users[i].pubKey.serialize()); + } + }); + + it("should publish 200 messages (some for non signed up users)", async () => { + for (let i = 0; i < 2; i += 1) { + // eslint-disable-next-line @typescript-eslint/prefer-for-of + for (let j = 0; j < users.length; j += 1) { + const randomVoteOption = Math.floor(Math.random() * 126); + const randomVoteWeight = Math.floor(Math.random() * 10); + // eslint-disable-next-line no-await-in-loop + await publish( + users[j].pubKey.serialize(), + j + 1, + randomVoteOption, + 1, + 0, + randomVoteWeight, + maciAddresses.maciAddress, + genRandomSalt().toString(), + users[j].privKey.serialize(), + ); + } + } + }); + + it("should generate zk-SNARK proofs and verify them", async () => { + await timeTravel(pollDuration); + await mergeMessages(0, maciAddresses.maciAddress); + await mergeSignups(0, maciAddresses.maciAddress); + const tallyFileData = await genProofs( + testProofsDirPath, + testTallyFilePath, + ceremonyTallyVotesZkeyPath, + ceremonyProcessMessageZkeyPath, + 0, + undefined, + undefined, + testRapidsnarkPath, + cermeonyProcessMessagesWitnessPath, + ceremonyTallyVotesWitnessPath, + undefined, + coordinatorPrivKey, + maciAddresses.maciAddress, + undefined, + ceremonyProcessMessagesWasmPath, + ceremonyTallyVotesWasmPath, + undefined, + useWasm, + undefined, + undefined, + undefined, + undefined, + 300, + ); + await proveOnChain("0", testProofsDirPath, subsidyEnabled); + await verify( + "0", + subsidyEnabled, + testTallyFilePath, + tallyFileData, + maciAddresses.maciAddress, + pollAddresses.tally, + ); + }); + }); + + describe("1000 signups, 5000 messages", () => { + const thousandUsers = Array(1000).fill(new Keypair()); + + after(() => { + cleanVanilla(); + }); + + before(async () => { + // deploy the smart contracts + maciAddresses = await deploy(stateTreeDepth); + // deploy a poll contract + pollAddresses = await deployPoll( + pollDuration, + maxMessages, + maxVoteOptions, + intStateTreeDepth, + messageBatchDepth, + messageTreeDepth, + voteOptionTreeDepth, + coordinatorPubKey, + subsidyEnabled, + ); + }); + + it("should signup 1000 users", async () => { + // eslint-disable-next-line @typescript-eslint/prefer-for-of + for (let i = 0; i < thousandUsers.length; i += 1) { + // eslint-disable-next-line no-await-in-loop + await signup(thousandUsers[i].pubKey.serialize()); + } + }); + + it("should publish 5000 messages (some for non signed up users)", async () => { + for (let i = 0; i < 5; i += 1) { + // eslint-disable-next-line @typescript-eslint/prefer-for-of + for (let j = 0; j < thousandUsers.length; j += 1) { + const randomVoteOption = Math.floor(Math.random() * 126); + const randomVoteWeight = Math.floor(Math.random() * 10); + // eslint-disable-next-line no-await-in-loop + await publish( + thousandUsers[j].pubKey.serialize(), + j + 1, + randomVoteOption, + 1, + 0, + randomVoteWeight, + maciAddresses.maciAddress, + genRandomSalt().toString(), + thousandUsers[j].privKey.serialize(), + ); + } + } + }); + + it("should generate zk-SNARK proofs and verify them", async () => { + await timeTravel(pollDuration); + await mergeMessages(0, maciAddresses.maciAddress); + await mergeSignups(0, maciAddresses.maciAddress); + const tallyFileData = await genProofs( + testProofsDirPath, + testTallyFilePath, + ceremonyTallyVotesZkeyPath, + ceremonyProcessMessageZkeyPath, + 0, + undefined, + undefined, + testRapidsnarkPath, + cermeonyProcessMessagesWitnessPath, + ceremonyTallyVotesWitnessPath, + undefined, + coordinatorPrivKey, + maciAddresses.maciAddress, + undefined, + ceremonyProcessMessagesWasmPath, + ceremonyTallyVotesWasmPath, + undefined, + useWasm, + undefined, + undefined, + undefined, + undefined, + 300, + ); + await proveOnChain("0", testProofsDirPath, subsidyEnabled); + await verify( + "0", + subsidyEnabled, + testTallyFilePath, + tallyFileData, + maciAddresses.maciAddress, + pollAddresses.tally, + ); + }); + }); +}); diff --git a/cli/ts/commands/genProofs.ts b/cli/ts/commands/genProofs.ts index 07a9e54ab0..fd14a20d5c 100644 --- a/cli/ts/commands/genProofs.ts +++ b/cli/ts/commands/genProofs.ts @@ -83,6 +83,7 @@ export const genProofs = async ( startBlock?: number, blocksPerBatch?: number, endBlock?: number, + sleepFetch?: number, quiet = true, ): Promise => { banner(quiet); @@ -271,6 +272,7 @@ export const genProofs = async ( fromBlock, blocksPerBatch, endBlock, + sleepFetch, ); } diff --git a/cli/ts/index.ts b/cli/ts/index.ts index 90eda32765..d01cc24bd8 100644 --- a/cli/ts/index.ts +++ b/cli/ts/index.ts @@ -406,6 +406,7 @@ program .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) .option("-bb, --blocks-per-batch ", "the number of blocks to process per batch", parseInt) + .option("-sf, --sleep-fetch ", "the sleep time between fetching batches", parseInt) .action(async (cmdObj) => { try { await genProofs( @@ -431,6 +432,7 @@ program cmdObj.startBlock, cmdObj.endBlock, cmdObj.blocksPerBatch, + cmdObj.sleepFetch, cmdObj.quiet, ); } catch (error) { diff --git a/package.json b/package.json index 2930818d2c..ab9e386d3b 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "test:cli": "lerna run test --scope \"maci-cli\"", "test:integration": "lerna run test --scope \"maci-integrationtests\"", "test": "lerna run test --ignore maci-integrationtests --ignore maci-cli", + "test:stress": "lerna run test:stress --scope \"maci-cli\"", "types": "lerna run types", "typedoc": "typedoc --plugin typedoc-plugin-markdown --options typedoc.json", "prepare": "is-ci || husky install"