Skip to content

Commit

Permalink
refactor: optimize deployment and tally event
Browse files Browse the repository at this point in the history
- [x] Update integration and cli docs
- [x] Add poseidon contract addresses as cli arguments
- [x] Add BallotsTallied(address) event for Tally contract
- [x] Reuse already deployed poseidon contracts
  • Loading branch information
0xmad committed Jan 22, 2024
1 parent 24c0bd4 commit eea66aa
Show file tree
Hide file tree
Showing 21 changed files with 228 additions and 113 deletions.
3 changes: 2 additions & 1 deletion .solhint.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"max-line-length": ["warn", 120],
"quotes": ["error", "double"],
"func-visibility": ["error", { "ignoreConstructors": true }],
"state-visibility": "error"
"state-visibility": "error",
"immutable-vars-naming": ["warn", { "immutablesAsConstants": false }]
}
}
24 changes: 16 additions & 8 deletions cli/tests/unit/topup.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,23 @@ describe("topup", () => {
const signupGatekepper = await deployFreeForAllSignUpGatekeeper(signer, true);
const topupCredit = await deployTopupCredit(signer, true);
const initialVoiceCreditProxyAddress = await deployConstantInitialVoiceCreditProxy(100, signer, true);
const maciContracts = await deployMaci(
await signupGatekepper.getAddress(),
await initialVoiceCreditProxyAddress.getAddress(),
await topupCredit.getAddress(),
const [signUpTokenGatekeeperContractAddress, initialVoiceCreditBalanceAddress, topupCreditContractAddress] =
await Promise.all([
signupGatekepper.getAddress(),
initialVoiceCreditProxyAddress.getAddress(),
topupCredit.getAddress(),
]);

const { maciContract } = await deployMaci({
signUpTokenGatekeeperContractAddress,
initialVoiceCreditBalanceAddress,
topupCreditContractAddress,
signer,
10,
true,
);
maciAddress = await maciContracts.maciContract.getAddress();
stateTreeDepth: 10,
quiet: true,
});

maciAddress = await maciContract.getAddress();
});

it("should throw when the state index is invalid", async () => {
Expand Down
38 changes: 24 additions & 14 deletions cli/ts/commands/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ export const deploy = async ({
initialVoiceCredits,
initialVoiceCreditsProxyAddress,
signupGatekeeperAddress,
poseidonT3Address = readContractAddress("PoseidonT3"),
poseidonT4Address = readContractAddress("PoseidonT4"),
poseidonT5Address = readContractAddress("PoseidonT5"),
poseidonT6Address = readContractAddress("PoseidonT6"),
quiet = true,
}: DeployArgs): Promise<DeployedContracts> => {
banner(quiet);
Expand Down Expand Up @@ -71,14 +75,20 @@ export const deploy = async ({
]);

// deploy MACI, stateAq, PollFactory and poseidon
const { maciContract, stateAqContract, pollFactoryContract, poseidonAddrs } = await deployMaci(
signupGatekeeperContractAddress,
initialVoiceCreditProxyContractAddress!,
topUpCreditAddress,
const { maciContract, stateAqContract, pollFactoryContract, poseidonAddrs } = await deployMaci({
signUpTokenGatekeeperContractAddress: signupGatekeeperContractAddress,
initialVoiceCreditBalanceAddress: initialVoiceCreditProxyContractAddress!,
topupCreditContractAddress: topUpCreditAddress,
poseidonAddresses: {
poseidonT3: poseidonT3Address,
poseidonT4: poseidonT4Address,
poseidonT5: poseidonT5Address,
poseidonT6: poseidonT6Address,
},
signer,
stateTreeDepth,
true,
);
quiet: true,
});

const [maciContractAddress, stateAqContractAddress, pollFactoryContractAddress] = await Promise.all([
maciContract.getAddress(),
Expand All @@ -94,10 +104,10 @@ export const deploy = async ({
storeContractAddress("StateAq", stateAqContractAddress);
storeContractAddress("PollFactory", pollFactoryContractAddress);
storeContractAddress("TopupCredit", topUpCreditAddress);
storeContractAddress("PoseidonT3", poseidonAddrs[0]);
storeContractAddress("PoseidonT4", poseidonAddrs[1]);
storeContractAddress("PoseidonT5", poseidonAddrs[2]);
storeContractAddress("PoseidonT6", poseidonAddrs[3]);
storeContractAddress("PoseidonT3", poseidonAddrs.poseidonT3);
storeContractAddress("PoseidonT4", poseidonAddrs.poseidonT4);
storeContractAddress("PoseidonT5", poseidonAddrs.poseidonT5);
storeContractAddress("PoseidonT6", poseidonAddrs.poseidonT6);

logGreen(quiet, success(`MACI deployed at: ${maciContractAddress}`));

Expand All @@ -108,10 +118,10 @@ export const deploy = async ({
pollFactoryAddress: pollFactoryContractAddress,
verifierAddress: verifierContractAddress,
topupCreditAddress: topUpCreditAddress,
poseidonT3Address: poseidonAddrs[0],
poseidonT4Address: poseidonAddrs[1],
poseidonT5Address: poseidonAddrs[2],
poseidonT6Address: poseidonAddrs[3],
poseidonT3Address: poseidonAddrs.poseidonT3,
poseidonT4Address: poseidonAddrs.poseidonT4,
poseidonT5Address: poseidonAddrs.poseidonT5,
poseidonT6Address: poseidonAddrs.poseidonT6,
signUpGatekeeperAddress: signupGatekeeperContractAddress,
initialVoiceCreditProxyAddress: initialVoiceCreditProxyContractAddress!,
};
Expand Down
8 changes: 8 additions & 0 deletions cli/ts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ program
"-p, --initialVoiceCreditsProxyAddress <initialVoiceCreditsProxyAddress>",
"the initial voice credits proxy contract address",
)
.option("-ph3, --poseidonT3Address <poseidonT3Address>", "PoseidonT3 contract address")
.option("-ph4, --poseidonT4Address <poseidonT4Address>", "PoseidonT4 contract address")
.option("-ph5, --poseidonT5Address <poseidonT5Address>", "PoseidonT5 contract address")
.option("-ph6, --poseidonT6Address <poseidonT6Address>", "PoseidonT6 contract address")
.option("-g, --signupGatekeeperAddress <signupGatekeeperAddress>", "the signup gatekeeper contract address")
.option("-q, --quiet <quiet>", "whether to print values to the console", (value) => value === "true", false)
.option("-r, --rpc-provider <provider>", "the rpc provider URL")
Expand All @@ -55,6 +59,10 @@ program
initialVoiceCredits: cmdOptions.initialVoiceCredits,
initialVoiceCreditsProxyAddress: cmdOptions.initialVoiceCreditsProxyAddress,
signupGatekeeperAddress: cmdOptions.signupGatekeeperAddress,
poseidonT3Address: cmdOptions.poseidonT3Address,
poseidonT4Address: cmdOptions.poseidonT4Address,
poseidonT5Address: cmdOptions.poseidonT5Address,
poseidonT6Address: cmdOptions.poseidonT6Address,
quiet: cmdOptions.quiet,
});
} catch (error) {
Expand Down
20 changes: 20 additions & 0 deletions cli/ts/utils/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,26 @@ export interface DeployArgs {
*/
signupGatekeeperAddress?: string;

/**
* The address of the PoseidonT3 contract
*/
poseidonT3Address?: string;

/**
* The address of the PoseidonT4 contract
*/
poseidonT4Address?: string;

/**
* The address of the PoseidonT5 contract
*/
poseidonT5Address?: string;

/**
* The address of the PoseidonT6 contract
*/
poseidonT6Address?: string;

/**
* Whether to log the output
*/
Expand Down
15 changes: 5 additions & 10 deletions contracts/contracts/MACI.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ contract MACI is IMACI, Params, Utilities, Ownable {
/// @notice The state tree depth is fixed. As such it should be as large as feasible
/// so that there can be as many users as possible. i.e. 5 ** 10 = 9765625
/// this should also match the parameter of the circom circuits.
uint8 public immutable STATE_TREE_DEPTH;
uint8 public immutable stateTreeDepth;

/// @notice IMPORTANT: remember to change the ballot tree depth
/// in contracts/ts/genEmptyBallotRootsContract.ts file
Expand Down Expand Up @@ -133,17 +133,12 @@ contract MACI is IMACI, Params, Utilities, Ownable {
topupCredit = _topupCredit;
signUpGatekeeper = _signUpGatekeeper;
initialVoiceCreditProxy = _initialVoiceCreditProxy;
STATE_TREE_DEPTH = _stateTreeDepth;
stateTreeDepth = _stateTreeDepth;

// Verify linked poseidon libraries
if (hash2([uint256(1), uint256(1)]) == 0) revert PoseidonHashLibrariesNotLinked();
}

/// @inheritdoc IMACI
function stateTreeDepth() external view returns (uint8) {
return STATE_TREE_DEPTH;
}

/// @notice Allows any eligible user sign up. The sign-up gatekeeper should prevent
/// double sign-ups or ineligible users from doing so. This function will
/// only succeed if the sign-up deadline has not passed. It also enqueues a
Expand All @@ -162,7 +157,7 @@ contract MACI is IMACI, Params, Utilities, Ownable {
bytes memory _initialVoiceCreditProxyData
) public {
// ensure we do not have more signups than what the circuits support
if (numSignUps == uint256(TREE_ARITY) ** uint256(STATE_TREE_DEPTH)) revert TooManySignups();
if (numSignUps == uint256(TREE_ARITY) ** uint256(stateTreeDepth)) revert TooManySignups();

if (_pubKey.x >= SNARK_SCALAR_FIELD || _pubKey.y >= SNARK_SCALAR_FIELD) {
revert MaciPubKeyLargerThanSnarkFieldSize();
Expand Down Expand Up @@ -264,12 +259,12 @@ contract MACI is IMACI, Params, Utilities, Ownable {

/// @inheritdoc IMACI
function mergeStateAq(uint256 _pollId) public override onlyPoll(_pollId) returns (uint256 root) {
root = stateAq.merge(STATE_TREE_DEPTH);
root = stateAq.merge(stateTreeDepth);
}

/// @inheritdoc IMACI
function getStateAqRoot() public view override returns (uint256 root) {
root = stateAq.getMainRoot(STATE_TREE_DEPTH);
root = stateAq.getMainRoot(stateTreeDepth);
}

/// @notice Get the Poll details
Expand Down
15 changes: 11 additions & 4 deletions contracts/contracts/Tally.sol
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ contract Tally is Ownable, SnarkCommon, CommonUtilities, Hasher {
IVerifier public immutable verifier;
IVkRegistry public immutable vkRegistry;
IPoll public immutable poll;
IMessageProcessor public immutable mp;
IMessageProcessor public immutable messageProcessor;

/// @notice custom errors
error ProcessingNotComplete();
Expand All @@ -49,6 +49,9 @@ contract Tally is Ownable, SnarkCommon, CommonUtilities, Hasher {
error BatchStartIndexTooLarge();
error TallyBatchSizeTooLarge();

/// @notice events
event BallotsTallied(address poll);

/// @notice Create a new Tally contract
/// @param _verifier The Verifier contract
/// @param _vkRegistry The VkRegistry contract
Expand All @@ -58,7 +61,7 @@ contract Tally is Ownable, SnarkCommon, CommonUtilities, Hasher {
verifier = IVerifier(_verifier);
vkRegistry = IVkRegistry(_vkRegistry);
poll = IPoll(_poll);
mp = IMessageProcessor(_mp);
messageProcessor = IMessageProcessor(_mp);
}

/// @notice Pack the batch start index and number of signups into a 100-bit value.
Expand Down Expand Up @@ -102,12 +105,12 @@ contract Tally is Ownable, SnarkCommon, CommonUtilities, Hasher {
/// @notice Update the state and ballot root commitment
function updateSbCommitment() public onlyOwner {
// Require that all messages have been processed
if (!mp.processingComplete()) {
if (!messageProcessor.processingComplete()) {
revert ProcessingNotComplete();
}

if (sbCommitment == 0) {
sbCommitment = mp.sbCommitment();
sbCommitment = messageProcessor.sbCommitment();
}
}

Expand Down Expand Up @@ -135,6 +138,10 @@ contract Tally is Ownable, SnarkCommon, CommonUtilities, Hasher {
// Update the tally commitment and the tally batch num
tallyCommitment = _newTallyCommitment;
tallyBatchNum++;

if (tallyBatchNum * tallyBatchSize > numSignUps) {
emit BallotsTallied(address(poll));
}
}

/// @notice Verify the tally proof using the verifying key
Expand Down
Loading

0 comments on commit eea66aa

Please sign in to comment.