Skip to content

Commit

Permalink
unify private and public voting results
Browse files Browse the repository at this point in the history
  • Loading branch information
eugene-babichenko authored and Mikhail Zabaluev committed Oct 19, 2020
1 parent f6f5f3d commit a4c2e88
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 10 deletions.
16 changes: 13 additions & 3 deletions chain-impl-mockchain/src/vote/manager.rs
@@ -1,4 +1,4 @@
use crate::vote::{Payload, PayloadType, TallyError};
use crate::vote::{Choice, Payload, PayloadType, TallyError};
use crate::{
certificate::{Proposal, VoteAction, VoteCast, VotePlan, VotePlanId},
date::BlockDate,
Expand Down Expand Up @@ -75,7 +75,6 @@ pub enum VoteError {

#[error("Cannot tally votes")]
CannotTallyVotes {
#[source]
#[from]
source: vote::TallyError,
},
Expand Down Expand Up @@ -216,14 +215,25 @@ impl ProposalManager {
&self,
shares: &[chain_vote::TallyDecryptShare],
) -> Result<Self, TallyError> {
use std::convert::TryInto;
match &self.tally {
Some(Tally::Private { tally, .. }) => {
let state = tally.state();
let max_votes = self.votes_by_voters.size();
let table_size: usize = max_votes
.checked_div(self.options.as_byte() as usize)
.unwrap_or(max_votes / 3);
let result = chain_vote::result(max_votes as u64, table_size, &state, shares);
let private_result =
chain_vote::result(max_votes as u64, table_size, &state, shares);
let mut result = TallyResult::new(self.options.clone());
for (choice, weight) in private_result
.votes
.iter()
.map(|maybe_vote| maybe_vote.unwrap_or_default())
.enumerate()
{
result.add_vote(Choice::new(choice.try_into()?), weight)?;
}
Ok(Self {
votes_by_voters: self.votes_by_voters.clone(),
options: self.options.clone(),
Expand Down
25 changes: 18 additions & 7 deletions chain-impl-mockchain/src/vote/tally.rs
Expand Up @@ -28,7 +28,7 @@ pub enum Tally {
},
Private {
tally: chain_vote::Tally,
result: Option<chain_vote::TallyResult>,
result: Option<TallyResult>,
},
}

Expand All @@ -38,6 +38,11 @@ pub enum TallyError {
InvalidChoice { options: Options, choice: Choice },
#[error("Invalid privacy")]
InvalidPrivacy,
#[error("Choice number in private vote was too high. Maximum of 255 is allowed.")]
InvalidPrivateChoiceSize {
#[from]
source: std::num::TryFromIntError,
},
}

impl Weight {
Expand All @@ -55,21 +60,27 @@ impl Tally {
pub fn new_public(result: TallyResult) -> Self {
Self::Public { result }
}
pub fn new_private(tally: chain_vote::Tally, result: Option<chain_vote::TallyResult>) -> Self {
pub fn new_private(tally: chain_vote::Tally, result: Option<TallyResult>) -> Self {
Self::Private { tally, result }
}

pub fn is_public(&self) -> bool {
self.public().is_some()
match self {
Self::Public { .. } => true,
_ => false,
}
}
pub fn is_private(&self) -> bool {
self.private().is_some()
match self {
Self::Private { .. } => true,
_ => false,
}
}

pub fn public(&self) -> Option<&TallyResult> {
pub fn result(&self) -> Option<&TallyResult> {
match self {
Self::Public { result } => Some(result),
_ => None,
Self::Private { result, .. } => result.as_ref(),
}
}

Expand Down Expand Up @@ -235,6 +246,6 @@ mod tests {
#[quickcheck]
pub fn tally(tally_result: TallyResult) -> TestResult {
let tally = Tally::new_public(tally_result.clone());
TestResult::from_bool(tally.is_public() && (*tally.public().unwrap()) == tally_result)
TestResult::from_bool(tally.is_public() && (*tally.result().unwrap()) == tally_result)
}
}

0 comments on commit a4c2e88

Please sign in to comment.