Skip to content

Commit

Permalink
feat: use hash-based leader election instead of rand
Browse files Browse the repository at this point in the history
  • Loading branch information
NikitaMasych committed Aug 20, 2024
1 parent 70027e3 commit 55dc0b4
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 11 deletions.
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
rand = "0.9.0-alpha.2"
log = "0.4.22"
rkyv = { version = "0.7.44", features = ["validation"]}
serde = { version = "1.0.207", features = ["derive"] }
Expand Down
19 changes: 9 additions & 10 deletions src/party.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ use crate::message::{
MessagePacket, MessageRouting, ProtocolMessage,
};
use crate::{Value, ValueSelector};
use rand::prelude::StdRng;
use rand::prelude::*;
use rand::Rng;
use rkyv::{AlignedVec, Deserialize, Infallible};
use std::cmp::PartialEq;
use std::collections::hash_map::DefaultHasher;
Expand Down Expand Up @@ -236,15 +233,10 @@ impl<V: Value, VS: ValueSelector<V>> Party<V, VS> {
return Err(BallotError::LeaderElection("Zero weight sum".into()));
}

// Use the seed from the config to create a deterministic random number generator.
let mut rng = StdRng::seed_from_u64(seed);

let random_value: u64 = rng.gen_range(0..total_weight);

let mut cumulative_weight = 0;
for (i, &weight) in self.cfg.party_weights.iter().enumerate() {
cumulative_weight += weight;
if random_value < cumulative_weight {
if self.hash_to_range(seed, cumulative_weight) < weight {
return Ok(i as u64);
}
}
Expand All @@ -266,6 +258,13 @@ impl<V: Value, VS: ValueSelector<V>> Party<V, VS> {
hasher.finish()
}

/// Hash the seed to a value within a given range.
fn hash_to_range(&self, seed: u64, range: u64) -> u64 {
let mut hasher = DefaultHasher::new();
seed.hash(&mut hasher);
hasher.finish() % range
}

fn get_value(&self) -> V {
self.value_selector.select(&self.parties_voted_before)
}
Expand Down Expand Up @@ -1043,7 +1042,7 @@ mod tests {

// This party id is precomputed for this specific party_weights, threshold and ballot.
// Because we need leader to send 1a.
let party_id = 2;
let party_id = 0;

let (mut party, msg_out_receiver, _) =
Party::<MockValue, MockValueSelector>::new(party_id, cfg, MockValueSelector);
Expand Down

0 comments on commit 55dc0b4

Please sign in to comment.