Skip to content

Commit cd82d3c

Browse files
apollo_consensus: use instance fields instead of constants in sim test
1 parent 16c30b1 commit cd82d3c

File tree

1 file changed

+32
-16
lines changed

1 file changed

+32
-16
lines changed

crates/apollo_consensus/src/simulation_test.rs

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ use crate::types::{Decision, ProposalCommitment, Round, ValidatorId};
2626
use crate::votes_threshold::QuorumType;
2727

2828
const HEIGHT_0: BlockNumber = BlockNumber(0);
29-
const TOTAL_NODES: usize = 100;
30-
const THRESHOLD: usize = (2 * TOTAL_NODES / 3) + 1;
3129
const NODE_0_LEADER_PROBABILITY: f64 = 0.1;
3230
const NODE_UNDER_TEST: usize = 0;
3331

@@ -137,12 +135,16 @@ struct DiscreteEventSimulation {
137135
rng: StdRng,
138136
/// The seed used to initialize the simulation.
139137
seed: u64,
138+
/// Total number of nodes in the network.
139+
total_nodes: usize,
140+
/// Number of honest nodes (the rest are faulty).
141+
honest_nodes: usize,
142+
/// Quorum threshold for reaching consensus (2/3 + 1 of total nodes).
143+
quorum_threshold: usize,
140144
/// The single height consensus instance.
141145
shc: SingleHeightConsensus,
142146
/// All validators in the network.
143147
validators: Vec<ValidatorId>,
144-
/// Number of honest nodes (the rest are faulty).
145-
honest_nodes: usize,
146148
/// Priority queue of pending events that have yet to be processed (min-heap by tick).
147149
pending_events: BinaryHeap<TimedEvent>,
148150
/// Current simulation tick.
@@ -187,12 +189,16 @@ impl DiscreteEventSimulation {
187189
TimeoutsConfig::default(),
188190
);
189191

192+
let quorum_threshold = (2 * total_nodes / 3) + 1;
193+
190194
Self {
191195
rng,
192196
seed,
197+
total_nodes,
198+
honest_nodes,
199+
quorum_threshold,
193200
shc,
194201
validators,
195-
honest_nodes,
196202
pending_events: BinaryHeap::new(),
197203
current_tick: 0,
198204
processed_history: Vec::new(),
@@ -228,17 +234,17 @@ impl DiscreteEventSimulation {
228234
/// Other nodes share the remaining probability (1 - NODE_0_LEADER_PROBABILITY) uniformly.
229235
/// The selection is deterministic per round - the same round will always return the same
230236
/// leader index.
231-
fn get_leader_index(seed: u64, round: Round) -> usize {
237+
fn get_leader_index(&self, round: Round) -> usize {
232238
let round_u64 = u64::from(round);
233-
let round_seed = seed.wrapping_mul(31).wrapping_add(round_u64);
239+
let round_seed = self.seed.wrapping_mul(31).wrapping_add(round_u64);
234240
let mut round_rng = StdRng::seed_from_u64(round_seed);
235241

236242
let random_value: f64 = round_rng.gen();
237243

238244
if random_value < NODE_0_LEADER_PROBABILITY {
239245
NODE_UNDER_TEST
240246
} else {
241-
round_rng.gen_range(1..TOTAL_NODES)
247+
round_rng.gen_range(1..self.total_nodes)
242248
}
243249
}
244250

@@ -300,7 +306,7 @@ impl DiscreteEventSimulation {
300306
fn pre_generate_all_rounds(&mut self) {
301307
for round_idx in 0..self.num_rounds {
302308
let round = Round::from(u32::try_from(round_idx).unwrap());
303-
let leader_idx = Self::get_leader_index(self.seed, round);
309+
let leader_idx = self.get_leader_index(round);
304310
let leader_id = self.validators[leader_idx];
305311
// Track rounds where NODE_0 is the proposer.
306312
// We will schedule peer votes for these rounds after the build finish event.
@@ -407,7 +413,7 @@ impl DiscreteEventSimulation {
407413
}
408414
FaultType::NonValidator => {
409415
// Send votes with a voter ID that is outside the validator set
410-
let non_validator_id = ValidatorId::from(u64::try_from(TOTAL_NODES).unwrap());
416+
let non_validator_id = ValidatorId::from(u64::try_from(self.total_nodes).unwrap());
411417
self.schedule_prevote_and_precommit(
412418
non_validator_id,
413419
round,
@@ -460,8 +466,17 @@ impl DiscreteEventSimulation {
460466

461467
let validators = self.validators.clone();
462468
let seed = self.seed;
469+
let total_nodes = self.total_nodes;
463470
let leader_fn = move |r: Round| {
464-
let idx = Self::get_leader_index(seed, r);
471+
let round_u64 = u64::from(r);
472+
let round_seed = seed.wrapping_mul(31).wrapping_add(round_u64);
473+
let mut round_rng = StdRng::seed_from_u64(round_seed);
474+
let random_value: f64 = round_rng.gen();
475+
let idx = if random_value < NODE_0_LEADER_PROBABILITY {
476+
NODE_UNDER_TEST
477+
} else {
478+
round_rng.gen_range(1..total_nodes)
479+
};
465480
validators[idx]
466481
};
467482

@@ -603,7 +618,7 @@ fn verify_result(sim: &DiscreteEventSimulation, result: Option<&Decision>) {
603618
.count();
604619
let total_precommits = peer_precommits + self_vote;
605620

606-
if total_precommits >= THRESHOLD {
621+
if total_precommits >= sim.quorum_threshold {
607622
Some((*r, *commitment, precommits.clone()))
608623
} else {
609624
None
@@ -657,10 +672,10 @@ fn verify_result(sim: &DiscreteEventSimulation, result: Option<&Decision>) {
657672

658673
// Verify quorum threshold is met
659674
assert!(
660-
actual.precommits.len() >= THRESHOLD,
675+
actual.precommits.len() >= sim.quorum_threshold,
661676
"Insufficient precommits in decision: {}/{}. Decision: {:?}, History: {:?}",
662677
actual.precommits.len(),
663-
THRESHOLD,
678+
sim.quorum_threshold,
664679
actual,
665680
sim.processed_history
666681
);
@@ -686,13 +701,14 @@ fn verify_result(sim: &DiscreteEventSimulation, result: Option<&Decision>) {
686701
fn test_consensus_simulation(keep_ratio: f64, honest_nodes: usize) {
687702
let seed = rand::thread_rng().gen();
688703
let num_rounds = 5; // Number of rounds to pre-generate
704+
let total_nodes = 100;
689705
println!(
690-
"Running consensus simulation with total nodes {TOTAL_NODES}, {num_rounds} rounds, keep \
706+
"Running consensus simulation with total nodes {total_nodes}, {num_rounds} rounds, keep \
691707
ratio {keep_ratio}, honest nodes {honest_nodes} and seed: {seed}"
692708
);
693709

694710
let mut sim =
695-
DiscreteEventSimulation::new(TOTAL_NODES, honest_nodes, seed, num_rounds, keep_ratio);
711+
DiscreteEventSimulation::new(total_nodes, honest_nodes, seed, num_rounds, keep_ratio);
696712

697713
let deadline_ticks = u64::try_from(num_rounds).unwrap() * ROUND_DURATION;
698714
let result = sim.run(deadline_ticks);

0 commit comments

Comments
 (0)