diff --git a/cli/package.json b/cli/package.json index a59e7775a2..25a06483cf 100644 --- a/cli/package.json +++ b/cli/package.json @@ -37,6 +37,7 @@ "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:signup": "ts-mocha --exit tests/unit/signup.test.ts", "test:utils": "ts-mocha --exit tests/unit/utils.test.ts", "docs": "typedoc --plugin typedoc-plugin-markdown --options ./typedoc.json" }, diff --git a/cli/tests/unit/signup.test.ts b/cli/tests/unit/signup.test.ts new file mode 100644 index 0000000000..a6aee95486 --- /dev/null +++ b/cli/tests/unit/signup.test.ts @@ -0,0 +1,70 @@ +import { expect } from "chai"; +import { Signer } from "ethers"; +import { getDefaultSigner } from "maci-contracts"; +import { Keypair } from "maci-domainobjs"; + +import { + deploy, + DeployedContracts, + deployVkRegistryContract, + isRegisteredUser, + setVerifyingKeys, + signup, +} from "../../ts"; +import { deployArgs, setVerifyingKeysArgs } from "../constants"; + +describe("signup", () => { + let signer: Signer; + let maciAddresses: DeployedContracts; + const user = new Keypair(); + // before all tests we deploy the vk registry contract and set the verifying keys + before(async () => { + signer = await getDefaultSigner(); + + // we deploy the vk registry contract + await deployVkRegistryContract({ signer }); + // we set the verifying keys + await setVerifyingKeys({ ...setVerifyingKeysArgs, signer }); + // deploy the smart contracts + maciAddresses = await deploy({ ...deployArgs, signer }); + }); + + it("should allow to signup and return the user data", async () => { + const signUpData = await signup({ + maciAddress: maciAddresses.maciAddress, + maciPubKey: user.pubKey.serialize(), + signer, + }); + + const registeredUserData = await isRegisteredUser({ + maciAddress: maciAddresses.maciAddress, + startBlock: await signer.provider?.getBlockNumber(), + maciPubKey: user.pubKey.serialize(), + signer, + }); + + expect(registeredUserData.isRegistered).to.eq(true); + expect(registeredUserData.stateIndex).to.eq(signUpData.stateIndex); + }); + + it("should not get the user data if the user is not registered", async () => { + const registeredUserData = await isRegisteredUser({ + maciAddress: maciAddresses.maciAddress, + startBlock: await signer.provider?.getBlockNumber(), + maciPubKey: new Keypair().pubKey.serialize(), + signer, + }); + + expect(registeredUserData.isRegistered).to.eq(false); + }); + + it("should start fetchig from block zero if the start block is not provided", async () => { + const registeredUserData = await isRegisteredUser({ + maciAddress: maciAddresses.maciAddress, + maciPubKey: user.pubKey.serialize(), + signer, + }); + + expect(registeredUserData.isRegistered).to.eq(true); + }); +}); diff --git a/cli/ts/commands/signup.ts b/cli/ts/commands/signup.ts index 5feef5949c..4948b12901 100644 --- a/cli/ts/commands/signup.ts +++ b/cli/ts/commands/signup.ts @@ -103,12 +103,29 @@ export const isRegisteredUser = async ({ const maciContract = MACIFactory.connect(maciAddress, signer); const publicKey = PubKey.deserialize(maciPubKey).asContractParam(); - const events = await maciContract.queryFilter( - maciContract.filters.SignUp(undefined, publicKey.x, publicKey.y), - startBlock, - ); - const stateIndex = events[0]?.args[0].toString() as string | undefined; - const voiceCredits = events[0]?.args[3].toString() as string | undefined; + // if no start block is provided we start from 0 + const startBlockNumber = startBlock || 0; + const currentBlock = await signer.provider!.getBlockNumber(); + + let event; + // 1000 blocks at a time + for (let block = startBlockNumber; block <= currentBlock; block += 1000) { + const toBlock = Math.min(block + 999, currentBlock); + // eslint-disable-next-line no-await-in-loop + const newEvents = await maciContract.queryFilter( + maciContract.filters.SignUp(undefined, publicKey.x, publicKey.y), + block, + toBlock, + ); + + if (newEvents.length > 0) { + [event] = newEvents; + break; + } + } + + const stateIndex = event?.args[0].toString(); + const voiceCredits = event?.args[3].toString(); logGreen(quiet, success(`State index: ${stateIndex?.toString()}, registered: ${stateIndex !== undefined}`));