Skip to content

Commit

Permalink
feat(genLocalState) - add e2e test, add sleep feature to prevent rate…
Browse files Browse the repository at this point in the history
… limiting, change utility name, add better error handling
  • Loading branch information
ctrlc03 committed Nov 9, 2023
1 parent 95ba802 commit 808ac9d
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 38 deletions.
49 changes: 49 additions & 0 deletions cli/tests/prepare_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,55 @@ clean() {

}

gen_proofs_pre_fetch() {
echo "merge messages ..."
$MACI_CLI mergeMessages \
--poll-id $1

echo "merge signups ..."
$MACI_CLI mergeSignups \
--poll-id $1

echo "gen proofs ..."

# generate the local state
$MACI_CLI genLocalState \
--poll-id $1 \
--output localState.json \
--privkey macisk.49953af3585856f539d194b46c82f4ed54ec508fb9b882940cbe68bbc57e59e \
--num-blocks-per-request 50

ARCH=$(uname -m)
if [[ $ARCH == *"arm"* ]]; then
# ARM parameters
$MACI_CLI genProofs \
--privkey macisk.49953af3585856f539d194b46c82f4ed54ec508fb9b882940cbe68bbc57e59e \
--poll-id $1 \
--process-wasm ./zkeys/ProcessMessages_"$PROCESS_MESSAGES_PARAMS"_js/ProcessMessages_"$PROCESS_MESSAGES_PARAMS".wasm \
--tally-wasm ./zkeys/TallyVotes_"$TALLY_VOTES_PARAMS"_js/TallyVotes_"$TALLY_VOTES_PARAMS".wasm \
--process-zkey "$ZKEYS_DIR"/ProcessMessages_"$PROCESS_MESSAGES_PARAMS".0.zkey \
--tally-zkey "$ZKEYS_DIR"/TallyVotes_"$TALLY_VOTES_PARAMS".0.zkey \
--tally-file tally.json \
--output proofs/ \
--state-file localState.json \
$SUBSIDDY_OPTION_GEN_PROOFS
else
# Intel parameters
$MACI_CLI genProofs \
--privkey macisk.49953af3585856f539d194b46c82f4ed54ec508fb9b882940cbe68bbc57e59e \
--poll-id $1 \
--rapidsnark ~/rapidsnark/build/prover \
--process-witnessgen ./zkeys/ProcessMessages_"$PROCESS_MESSAGES_PARAMS" \
--tally-witnessgen ./zkeys/TallyVotes_"$TALLY_VOTES_PARAMS" \
--process-zkey "$ZKEYS_DIR"/ProcessMessages_"$PROCESS_MESSAGES_PARAMS".0.zkey \
--tally-zkey "$ZKEYS_DIR"/TallyVotes_"$TALLY_VOTES_PARAMS".0.zkey \
--tally-file tally.json \
--output proofs/ \
--state-file localState.json \
$SUBSIDDY_OPTION_GEN_PROOFS
fi
}

gen_proofs() {
echo "merge messages ..."
$MACI_CLI mergeMessages \
Expand Down
35 changes: 35 additions & 0 deletions cli/tests/vanilla/testPreFetch.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/bin/bash

set -e

BASE_DIR="$(dirname "$BASH_SOURCE")"

. "$BASE_DIR"/../prepare_test.sh

# 1 signup and 1 message
clean

POLL_ID=0

init_maci
deploy_poll


$MACI_CLI signup \
--pubkey macipk.3e7bb2d7f0a1b7e980f1b6f363d1e3b7a12b9ae354c2cd60a9cfa9fd12917391

$MACI_CLI publish \
--pubkey macipk.3e7bb2d7f0a1b7e980f1b6f363d1e3b7a12b9ae354c2cd60a9cfa9fd12917391 \
--privkey macisk.fd7aa614ec4a82716ffc219c24fd7e7b52a2b63b5afb17e81c22fe21515539c \
--state-index 1 \
--vote-option-index 0 \
--new-vote-weight 9 \
--nonce 1 \
--poll-id "$POLL_ID"

$MACI_CLI timeTravel \
--seconds 90

gen_proofs_pre_fetch "$POLL_ID"

prove_and_verify_on_chain "$POLL_ID"
45 changes: 18 additions & 27 deletions cli/ts/fetchLogs.ts → cli/ts/genLocalState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import * as fs from 'fs'

import {
genMaciStateFromContract,
parseArtifact,
} from 'maci-contracts'

import {
Expand All @@ -20,10 +19,9 @@ import {readJSONFile} from 'maci-common'
import {contractFilepath} from './config'
import { Keypair, PrivKey } from 'maci-domainobjs'


const configureSubparser = (subparsers: any) => {
const parser = subparsers.addParser(
'fetchLogs',
'genLocalState',
{ addHelp: true },
)

Expand Down Expand Up @@ -116,9 +114,17 @@ const configureSubparser = (subparsers: any) => {
help: 'The output file for signups and messages',
}
)

parser.addArgument(
['-s', '--sleep'],
{
type: 'int',
help: 'The number of milliseconds to sleep between each RPC request to avoid getting rate limited',
}
)
}

const fetchLogs = async (args: any) => {
const genLocalState = async (args: any) => {
// read the contract addresses from the config file
const contractAddrs = readJSONFile(contractFilepath)

Expand All @@ -127,7 +133,7 @@ const fetchLogs = async (args: any) => {

// ensure we have at least one address
if ((!contractAddrs||!contractAddrs["MACI"]||!contractAddrs[pollArtifactName]) && !args.maci_contract && !args.poll_contract) {
console.error('Error: MACI and Poll contract addresses are empty or this poll Id does not exist')
console.error('Error: If no contract address is stored locally, please specify the poll id, the maci contract address and the poll address')
return
}
// prioritize cli flag arg
Expand All @@ -136,12 +142,12 @@ const fetchLogs = async (args: any) => {

// validate it's a valid eth address
if (!validateEthAddress(maciAddress)) {
console.error('Error: invalid MACI contract address')
console.error("Error: invalid MACI contract address. Ensure the address starts with '0x' followed by the 40 hexadecimal characters")
return
}

if (!validateEthAddress(pollAddress)) {
console.error("Error: invalid Poll contract address")
console.error("Error: invalid Poll contract address. Ensure the address starts with '0x' followed by the 40 hexadecimal characters")
return
}

Expand All @@ -160,22 +166,6 @@ const fetchLogs = async (args: any) => {
return
}

// fetch abis
const [ maciContractAbi ] = parseArtifact('MACI')
const [ pollContractAbi ] = parseArtifact('Poll')

const maciContract = new ethers.Contract(
maciAddress,
maciContractAbi,
provider,
)

const pollContract = new ethers.Contract(
pollAddress,
pollContractAbi,
provider
)

// The coordinator's MACI private key
let serializedPrivkey: string
if (args.prompt_for_maci_privkey) {
Expand All @@ -194,7 +184,6 @@ const fetchLogs = async (args: any) => {

// calculate the end block number
const endBlockNumber = args.end_block ? args.end_block : await provider.getBlockNumber()
console.log('Fetching logs till:', endBlockNumber)

console.log('Fetching signup and publish message logs')
// some rpc endpoint like bsc chain has limitation to retreive history logs
Expand All @@ -204,15 +193,17 @@ const fetchLogs = async (args: any) => {
const txn = await provider.getTransaction(txHash);
fromBlock = txn.blockNumber
}
console.log(`fromBlock = ${fromBlock}`)
console.log(`Fetching logs from ${fromBlock} till ${endBlockNumber} and generating the offline maci state`)

const maciState = await genMaciStateFromContract(
provider,
maciAddress,
coordinatorKeypair,
pollId,
fromBlock,
args.blocks_per_batch,
args.end_block
args.end_block,
args.sleep
)

// write the state to a file
Expand All @@ -221,6 +212,6 @@ const fetchLogs = async (args: any) => {
}

export {
fetchLogs,
genLocalState,
configureSubparser,
}
8 changes: 6 additions & 2 deletions cli/ts/genProofs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -418,9 +418,13 @@ const genProofs = async (args: any) => {
let maciState: MaciState
// Build an off-chain representation of the MACI contract using data in the contract storage
if (args.state_file) {
// @todo actually read the file first
const content = JSON.parse(fs.readFileSync(args.state_file, 'utf-8').toString())
maciState = MaciState.fromJSON(content)
try {
maciState = MaciState.fromJSON(content)
} catch (error: any) {
console.log('The provided state file is invalid. Please check that the correct path was provided and try again.')
return
}
// ensure we merge all messages
maciState.polls.forEach((poll: Poll) => poll.mergeAllMessages())
} else {
Expand Down
14 changes: 7 additions & 7 deletions cli/ts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,9 @@ import {
configureSubparser as configureSubparserForCheckVerifyKey,
} from './checkVerifyingKey'
import {
fetchLogs,
configureSubparser as configureSubparserForFetchLogs,
} from './fetchLogs'
genLocalState,
configureSubparser as configureSubparserForGenerateLocalState,
} from './genLocalState'

const main = async () => {
const parser = new argparse.ArgumentParser({
Expand Down Expand Up @@ -201,8 +201,8 @@ const main = async () => {
// Subcommand: checkVerifyKey
configureSubparserForCheckVerifyKey(subparsers)

// Subcommand: fetchlogs
configureSubparserForFetchLogs(subparsers)
// Subcommand: genLocalState
configureSubparserForGenerateLocalState(subparsers)

const args = parser.parseArgs()

Expand Down Expand Up @@ -245,8 +245,8 @@ const main = async () => {
await verify(args)
} else if (args.subcommand === 'checkVerifyingKey') {
await checkVerifyingKey(args)
} else if (args.subcommand === 'fetchLogs') {
await fetchLogs(args)
} else if (args.subcommand === 'genLocalState') {
await genLocalState(args)
}
}

Expand Down
22 changes: 20 additions & 2 deletions contracts/ts/genMaciState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
import { Contract, providers, utils } from 'ethers'
// import { assert } from 'assert'
import assert = require("assert")
import { sleep } from './utils'

interface Action {
type: string;
Expand All @@ -30,7 +31,8 @@ const genMaciStateFromContract = async (
pollId: number,
fromBlock: number = 0,
blocksPerRequest: number = 50,
endBlock?: number
endBlock?: number,
sleepAmount?: number
): Promise<MaciState> => {
pollId = Number(pollId)
// Verify and sort pollIds
Expand Down Expand Up @@ -73,6 +75,9 @@ const genMaciStateFromContract = async (
address: address
})

// sleep to avoid rate limiting
if (sleepAmount) await sleep(sleepAmount)

initLogs = initLogs.concat(tmpInitLogs)

const tmpSignUpLogs = await provider.getLogs({
Expand All @@ -82,6 +87,8 @@ const genMaciStateFromContract = async (
address: address
})

if (sleepAmount) await sleep(sleepAmount)

signUpLogs = signUpLogs.concat(tmpSignUpLogs)

const tmpMergeStateAqSubRootsLogs = await provider.getLogs({
Expand All @@ -91,6 +98,8 @@ const genMaciStateFromContract = async (
address: address
})

if (sleepAmount) await sleep(sleepAmount)

mergeStateAqSubRootsLogs = mergeStateAqSubRootsLogs.concat(tmpMergeStateAqSubRootsLogs)

const tmpMergeStateAqLogs = await provider.getLogs({
Expand All @@ -100,6 +109,8 @@ const genMaciStateFromContract = async (
address: address
})

if (sleepAmount) await sleep(sleepAmount)

mergeStateAqLogs = mergeStateAqLogs.concat(tmpMergeStateAqLogs)

const tmpDeployPollLogs = await provider.getLogs({
Expand All @@ -109,6 +120,8 @@ const genMaciStateFromContract = async (
address: address
})

if (sleepAmount) await sleep(sleepAmount)

deployPollLogs = deployPollLogs.concat(tmpDeployPollLogs)
}

Expand Down Expand Up @@ -289,6 +302,7 @@ const genMaciStateFromContract = async (
fromBlock: i,
toBlock
})
if (sleepAmount) await sleep(sleepAmount)

publishMessageLogs = publishMessageLogs.concat(tmpPublishMessageLogs)

Expand All @@ -298,6 +312,7 @@ const genMaciStateFromContract = async (
toBlock,
address: pollContract.address
})
if (sleepAmount) await sleep(sleepAmount)

topupLogs = topupLogs.concat(tmpTopupLogs)

Expand All @@ -307,6 +322,7 @@ const genMaciStateFromContract = async (
toBlock,
address: pollContract.address
})
if (sleepAmount) await sleep(sleepAmount)

mergeMaciStateAqSubRootsLogs = mergeMaciStateAqSubRootsLogs.concat(tmpMergeMaciStateAqSubRootsLogs)

Expand All @@ -316,6 +332,7 @@ const genMaciStateFromContract = async (
toBlock,
address: pollContract.address
})
if (sleepAmount) await sleep(sleepAmount)

mergeMaciStateAqLogs = mergeMaciStateAqLogs.concat(tmpMergeMaciStateAqLogs)

Expand All @@ -325,6 +342,7 @@ const genMaciStateFromContract = async (
toBlock,
address: pollContract.address
})
if (sleepAmount) await sleep(sleepAmount)

mergeMessageAqSubRootsLogs = mergeMessageAqSubRootsLogs.concat(tmpMergeMessageAqSubRootsLogs)

Expand All @@ -334,6 +352,7 @@ const genMaciStateFromContract = async (
toBlock,
address: pollContract.address
})
if (sleepAmount) await sleep(sleepAmount)

mergeMessageAqLogs = mergeMessageAqLogs.concat(tmpMergeMessageAqLogs)
}
Expand All @@ -355,7 +374,6 @@ const genMaciStateFromContract = async (
event.args._encPubKey.map((x) => BigInt(x.toString()))
)


actions.push({
type: 'PublishMessage',
// @ts-ignore
Expand Down
Loading

0 comments on commit 808ac9d

Please sign in to comment.