diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e91ff405c..3ad65ead5 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -267,6 +267,7 @@ jobs: uses: actions-rs/tarpaulin@v0.1 with: out-type: Html + timeout: 600 - name: Set branch name if: ${{ github.event_name == 'pull_request' }} diff --git a/chain-impl-mockchain/src/certificate/test.rs b/chain-impl-mockchain/src/certificate/test.rs index d541d8b90..5789eb12b 100644 --- a/chain-impl-mockchain/src/certificate/test.rs +++ b/chain-impl-mockchain/src/certificate/test.rs @@ -4,15 +4,20 @@ use crate::block::BlockDate; use crate::fragment::ConfigParams; use crate::ledger::governance::TreasuryGovernanceAction; use crate::rewards::TaxType; +use crate::testing::data::CommitteeMembersManager; use crate::vote; #[cfg(test)] use chain_core::mempack::{ReadBuf, Readable}; use chain_crypto::{testing, Ed25519}; use chain_time::DurationSeconds; +use chain_vote::{Crs, EncryptedTally}; #[cfg(test)] use quickcheck::TestResult; use quickcheck::{Arbitrary, Gen}; use quickcheck_macros::quickcheck; +use rand::SeedableRng; +use rand_chacha::ChaChaRng; +use std::num::NonZeroU8; impl Arbitrary for PoolRetirement { fn arbitrary(g: &mut G) -> Self { @@ -191,8 +196,6 @@ impl Arbitrary for Proposals { impl Arbitrary for VotePlan { fn arbitrary(g: &mut G) -> Self { - use rand_core::SeedableRng; - let vote_start = BlockDate::arbitrary(g); let vote_end = BlockDate::arbitrary(g); let committee_end = BlockDate::arbitrary(g); @@ -243,10 +246,53 @@ impl Arbitrary for VoteCast { } } +fn arbitrary_decrypted_private_tally(g: &mut G) -> DecryptedPrivateTally { + let proposals_n = u8::arbitrary(g); + let mut inner = Vec::new(); + let mut rng = ChaChaRng::seed_from_u64(u64::arbitrary(g)); + let crs_seed = String::arbitrary(g).into_bytes(); + let committee_size = (g.next_u32() % 2 + 1) as usize; // very time consuming + let committee_manager = + CommitteeMembersManager::new(&mut rng, &crs_seed, committee_size, committee_size); + + for _ in 0..proposals_n { + let n_options = NonZeroU8::arbitrary(g); + + let encrypted_tally = EncryptedTally::new( + n_options.get() as usize, + committee_manager.election_pk(), + Crs::from_hash(&crs_seed), + ); + + let mut decrypte_shares = Vec::new(); + for i in 0..committee_size { + decrypte_shares.push( + encrypted_tally + .partial_decrypt(&mut rng, committee_manager.members()[i].secret_key()), + ); + } + + inner.push(DecryptedPrivateTallyProposal { + tally_result: (0..n_options.get()) + .map(|_| u64::arbitrary(g)) + .collect::>(), + decrypt_shares: decrypte_shares.into_boxed_slice(), + }); + } + DecryptedPrivateTally::new(inner).unwrap() +} + impl Arbitrary for VoteTally { fn arbitrary(g: &mut G) -> Self { let vote_plan_id = VotePlanId::arbitrary(g); - Self::new_public(vote_plan_id) + + let private = bool::arbitrary(g); + + if private { + Self::new_private(vote_plan_id, arbitrary_decrypted_private_tally(g)) + } else { + Self::new_public(vote_plan_id) + } } }