Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(genLocalState) - debugging utility for log fetching and local maci state generation #758

Merged
merged 26 commits into from
Nov 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
03e4aa7
feat(fetch-logs) - add back fetch log and adapt to MACI v1
ctrlc03 Oct 20, 2023
bd0f964
feat(fetch logs) - update genMaciState to fetch logs in batches
ctrlc03 Oct 20, 2023
3d3d52e
refactor(fetchlogs) - remove fetchlogs in favor of genMaciState
ctrlc03 Oct 26, 2023
327e2ea
fix(logs) - do not make start block mandatory
ctrlc03 Oct 30, 2023
962eea4
fix(fetchlogs) - ensure we set a end block for fetching logs
ctrlc03 Oct 30, 2023
7267aa2
fix(fetchlogs) - ensure we are fetching logs coming from our desired …
ctrlc03 Oct 30, 2023
cc69e46
fix(contracts) - fix bug in genMaciState causing duplicate log fetching
ctrlc03 Oct 30, 2023
e9acf83
feat(fetchlogs) - ensure to use cli parameters to determine blocks pe…
ctrlc03 Nov 1, 2023
887dc59
feat(fetchlogs) - add maci state serialization
ctrlc03 Nov 2, 2023
ae72108
feat(fetchlogs) - add toJSON method to various domainobjs classes so …
ctrlc03 Nov 2, 2023
8788fd7
feat(fetchlogs) - add more serialization and deserialization methods
ctrlc03 Nov 7, 2023
f19c5fd
feat(fetchlogs) - ensure Poll equals function returns true after dese…
ctrlc03 Nov 7, 2023
530d7cb
feat(fetchlogs) - fix wrong deserialization of Keypair objects and en…
ctrlc03 Nov 7, 2023
a1a62ac
feat(fetchlogs) - ensure that we are deserializing the Command object…
ctrlc03 Nov 7, 2023
80255e6
feat(genLocalState) - add e2e test, add sleep feature to prevent rate…
ctrlc03 Nov 9, 2023
e9a4d36
feat(fetchlogs) - update documentation to show usage of the new commands
ctrlc03 Nov 14, 2023
f7eb5a3
feat(genLocalState) - ensure we are deleting the test file in the cor…
ctrlc03 Nov 14, 2023
f67b56f
feat(genLocalState) - fix issues with package-lock files
ctrlc03 Nov 14, 2023
ff73fd1
feat(genLocalState) - ensure we are passing the correct arguments to …
ctrlc03 Nov 15, 2023
b0d0d0d
feat(genLocalState) - do not store coordinator key but instead take i…
ctrlc03 Nov 20, 2023
efe151f
feat(genLocalState) - remove sleeps in between each log request, but …
ctrlc03 Nov 20, 2023
1cd4e27
feat(genLocalState) - remove coordinator key from fromJSON and add a …
ctrlc03 Nov 23, 2023
c56a558
feat(genLocalState) - sort out conflicts and ensure code runs correctly
ctrlc03 Nov 23, 2023
61b2591
feat(genLocalState) - fix corrupted package-lock file
ctrlc03 Nov 23, 2023
5002078
feat(genLocalState) - regenerate package-lock files
ctrlc03 Nov 23, 2023
f8e3c4a
feat(genLocalState) - ensure @types/chai version is consistent across…
ctrlc03 Nov 28, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,089 changes: 291 additions & 798 deletions circuits/package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion circuits/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"tmp": "^0.2.1"
},
"devDependencies": {
"@types/chai": "^4.3.9",
"@types/chai": "^4.3.11",
"@types/mocha": "^10.0.4",
"@types/node": "^18.11.9",
"chai": "^4.3.10",
Expand Down
5,997 changes: 16 additions & 5,981 deletions cli/package-lock.json

Large diffs are not rendered by default.

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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice demonstration of how to use new command!

$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 \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice demonstration of how to use new command +2

$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"
217 changes: 217 additions & 0 deletions cli/ts/genLocalState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
import * as ethers from 'ethers'
import * as fs from 'fs'

import {
genMaciStateFromContract,
} from 'maci-contracts'

import {
validateEthAddress,
contractExists,
promptPwd,
} from './utils'

import {
DEFAULT_ETH_PROVIDER,
} from './defaults'

import {readJSONFile} from 'maci-common'
import {contractFilepath} from './config'
import { Keypair, PrivKey } from 'maci-domainobjs'

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

const maciPrivkeyGroup = parser.addMutuallyExclusiveGroup({ required: true })

maciPrivkeyGroup.addArgument(
['-dsk', '--prompt-for-maci-privkey'],
{
action: 'storeTrue',
help: 'Whether to prompt for your serialized MACI private key',
}
)

maciPrivkeyGroup.addArgument(
['-sk', '--privkey'],
{
action: 'store',
type: 'string',
help: 'Your serialized MACI private key',
}
)

parser.addArgument(
['-e', '--eth-provider'],
{
action: 'store',
type: 'string',
help: `A connection string to an Ethereum provider. Default: ${DEFAULT_ETH_PROVIDER}`,
}
)

parser.addArgument(
['-x', '--maci-contract'],
{
required: false,
type: 'string',
help: 'The MACI contract address',
}
)

parser.addArgument(
['-i', '--poll-id'],
{
required: false,
type: 'int',
help: 'The Poll ID',
}
)

parser.addArgument(
['-p', '--poll-contract'],
{
required: false,
type: 'string',
help: 'The Poll contract address',
}
)

parser.addArgument(
['-b', '--start-block'],
{
type: 'int',
help: 'The block number at which the contract was deployed',
}
)

parser.addArgument(
['-f', '--end-block'],
{
required: false,
type: 'int',
help: 'The last block number to fetch logs from. If not specified, the current block number is used',
}
)

parser.addArgument(
['-n', '--num-blocks-per-request'],
{
required: true,
type: 'int',
help: 'The number of logs to fetch per RPC request',
}
)

parser.addArgument(
['-o', '--output'],
{
required: true,
type: 'string',
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 genLocalState = async (args: any) => {
// read the contract addresses from the config file
const contractAddrs = readJSONFile(contractFilepath)

const pollId = args.poll_id ? args.poll_id : 0
const pollArtifactName = `Poll-${pollId}`

// ensure we have at least one address
if ((!contractAddrs||!contractAddrs["MACI"]||!contractAddrs[pollArtifactName]) && !args.maci_contract && !args.poll_contract) {
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
const maciAddress = args.maci_contract ? args.maci_contract: contractAddrs["MACI"]
const pollAddress = args.poll_contract ? args.poll_contract: contractAddrs[pollArtifactName]

// validate it's a valid eth address
if (!validateEthAddress(maciAddress)) {
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. Ensure the address starts with '0x' followed by the 40 hexadecimal characters")
return
}

// Ethereum provider
const ethProvider = args.eth_provider ? args.eth_provider : DEFAULT_ETH_PROVIDER

const provider = new ethers.providers.JsonRpcProvider(ethProvider)

if (!(await contractExists(provider, maciAddress))) {
console.error('Error: there is no MACI contract deployed at the specified address')
return
}

if (!(await contractExists(provider, pollAddress))) {
console.error('Error: there is no Poll contract deployed at the specified address')
return
}

// The coordinator's MACI private key
let serializedPrivkey: string
if (args.prompt_for_maci_privkey) {
serializedPrivkey = await promptPwd('Your MACI private key')
} else {
serializedPrivkey = args.privkey
}

if (!PrivKey.isValidSerializedPrivKey(serializedPrivkey)) {
console.error('Error: invalid MACI private key')
return
}

const maciPrivkey = PrivKey.unserialize(serializedPrivkey)
const coordinatorKeypair = new Keypair(maciPrivkey)

// calculate the end block number
const endBlockNumber = args.end_block ? args.end_block : await provider.getBlockNumber()

console.log('Fetching signup and publish message logs')
// some rpc endpoint like bsc chain has limitation to retreive history logs
let fromBlock = args.start_block ? args.start_block : 0
const txHash = args.transaction_hash
if (txHash) {
const txn = await provider.getTransaction(txHash);
fromBlock = txn.blockNumber
}
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.sleep
)

// write the state to a file
const serializedState = maciState.toJSON()
fs.writeFileSync(args.output, JSON.stringify(serializedState, null, 4))
}

export {
genLocalState,
configureSubparser,
}
Loading
Loading