diff --git a/src/main.nr b/src/main.nr index cacf6a1..64294d7 100644 --- a/src/main.nr +++ b/src/main.nr @@ -3,6 +3,7 @@ mod test; contract EasyPrivateVoting { use dep::aztec::prelude::{AztecAddress, FunctionSelector, PrivateContext, Map, PublicMutable, SharedImmutable}; use dep::aztec::keys::getters::get_historical_public_keys; + #[aztec(storage)] struct Storage { admin: PublicMutable, // admin can end vote @@ -45,6 +46,7 @@ contract EasyPrivateVoting { assert(storage.admin.read().eq(context.msg_sender()), "Only admin can end votes"); // assert that caller is admin storage.vote_ended.write(true); } + unconstrained fn get_vote(candidate: Field) -> pub Field { storage.tally.at(candidate).read() } diff --git a/src/test/first.nr b/src/test/first.nr index 9452332..212d637 100644 --- a/src/test/first.nr +++ b/src/test/first.nr @@ -11,30 +11,21 @@ use dep::aztec::{oracle::{execution::{get_block_number, get_contract_address}, u use crate::EasyPrivateVoting; #[test] -unconstrained fn test_initializer() -> Field { - let (env, voting_contract_address, admin, _) = utils::setup(); +unconstrained fn test_initializer() { + let (_, voting_contract_address, admin) = utils::setup(); - std::println("======== Initializer ========="); - - let alice = env.create_account(); - let bob = env.create_account(); - - std::println("hello world"); - std::println(alice); - - let s = compute_secret_hash(0x01); - std::println(s); - - 1 + let block_number = get_block_number(); + let admin_slot = EasyPrivateVoting::storage().admin.slot; + let admin_storage_value = storage_read(voting_contract_address, admin_slot, block_number); + assert(admin_storage_value == admin, "Vote ended should be false"); } #[test] -unconstrained fn check_vote_status() { - let (env, voting_contract_address, admin, _) = utils::setup(); +unconstrained fn test_check_vote_status() { + let (_, voting_contract_address, _) = utils::setup(); let vote_ended_expected: bool = false; - env.impersonate(voting_contract_address); let block_number = get_block_number(); let status_slot = EasyPrivateVoting::storage().vote_ended.slot; let vote_ended_read: bool = storage_read(voting_contract_address, status_slot, block_number); @@ -43,9 +34,7 @@ unconstrained fn check_vote_status() { #[test] unconstrained fn test_end_vote() { - let (env, voting_contract_address, admin, _) = utils::setup(); - let alice = env.create_account(); - // std::println(f"Alice: {alice}"); + let (env, voting_contract_address, admin) = utils::setup(); env.impersonate(admin); let call_interface = EasyPrivateVoting::at(voting_contract_address).end_vote(); @@ -53,18 +42,25 @@ unconstrained fn test_end_vote() { let vote_ended_expected = true; - // need to impersonate the contract to correctly read the storage - env.impersonate(voting_contract_address); let block_number = get_block_number(); let status_slot = EasyPrivateVoting::storage().vote_ended.slot; let vote_ended_read: bool = storage_read(voting_contract_address, status_slot, block_number); assert(vote_ended_expected == vote_ended_read, "Vote ended should be true"); } -// this test is currently failing. I am debugging +#[test(should_fail)] +unconstrained fn test_fail_end_vote_by_non_admin() { + let (env, voting_contract_address, _) = utils::setup(); + let alice = env.create_account(); + + env.impersonate(alice); + let call_interface = EasyPrivateVoting::at(voting_contract_address).end_vote(); + env.call_public(call_interface); +} + #[test] unconstrained fn test_cast_vote() { - let (env, voting_contract_address, admin, _) = utils::setup(); + let (env, voting_contract_address, _) = utils::setup(); let alice = env.create_account(); env.impersonate(alice); @@ -72,13 +68,57 @@ unconstrained fn test_cast_vote() { env.advance_block_by(6); let call_interface = EasyPrivateVoting::at(voting_contract_address).cast_vote(candidate); env.call_private_void(call_interface); + + // Read vote count from storage + let block_number = get_block_number(); + let tally_slot = EasyPrivateVoting::storage().tally.slot; + let candidate_tally_slot = derive_storage_slot_in_map(tally_slot, candidate); + let vote_count: u32 = storage_read(voting_contract_address, candidate_tally_slot, block_number); + + assert(vote_count == 1, "vote tally should be incremented"); +} + +#[test] +unconstrained fn test_cast_vote_with_separate_accounts() { + let (env, voting_contract_address, _) = utils::setup(); + let alice = env.create_account(); + let bob = env.create_account(); + + let candidate = 101; + + env.impersonate(alice); + env.advance_block_by(1); + let call_interface = EasyPrivateVoting::at(voting_contract_address).cast_vote(candidate); + env.call_private_void(call_interface); + + env.impersonate(bob); + env.advance_block_by(1); + let call_interface = EasyPrivateVoting::at(voting_contract_address).cast_vote(candidate); + env.call_private_void(call_interface); + + // Read vote count from storage + let block_number = get_block_number(); + let tally_slot = EasyPrivateVoting::storage().tally.slot; + let candidate_tally_slot = derive_storage_slot_in_map(tally_slot, candidate); + let vote_count: u32 = storage_read(voting_contract_address, candidate_tally_slot, block_number); + + assert(vote_count == 2, "vote tally should be 2"); } #[test(should_fail)] -unconstrained fn test_end_vote_fail() { - let (env, voting_contract_address, admin, _) = utils::setup(); +unconstrained fn test_fail_vote_twice() { + let (env, voting_contract_address, _) = utils::setup(); let alice = env.create_account(); - let call_interface = EasyPrivateVoting::at(voting_contract_address).end_vote(); - env.call_public(call_interface); + let candidate = 101; + + env.impersonate(alice); + env.advance_block_by(1); + let call_interface = EasyPrivateVoting::at(voting_contract_address).cast_vote(candidate); + env.call_private_void(call_interface); + + // Vote again as alice + env.advance_block_by(1); + let call_interface = EasyPrivateVoting::at(voting_contract_address).cast_vote(candidate); + env.call_private_void(call_interface); }