Skip to content

Commit 66ce130

Browse files
apollo_consensus: use instance fields instead of constants in sim test
1 parent fc969b0 commit 66ce130

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
@@ -25,8 +25,6 @@ use crate::types::{Decision, ProposalCommitment, Round, ValidatorId};
2525
use crate::votes_threshold::QuorumType;
2626

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

@@ -128,12 +126,16 @@ struct DiscreteEventSimulation {
128126
rng: StdRng,
129127
/// The seed used to initialize the simulation.
130128
seed: u64,
129+
/// Total number of nodes in the network.
130+
total_nodes: usize,
131+
/// Number of honest nodes (the rest are faulty).
132+
honest_nodes: usize,
133+
/// Quorum threshold for reaching consensus (2/3 + 1 of total nodes).
134+
quorum_threshold: usize,
131135
/// The single height consensus instance.
132136
shc: SingleHeightConsensus,
133137
/// All validators in the network.
134138
validators: Vec<ValidatorId>,
135-
/// Number of honest nodes (the rest are faulty).
136-
honest_nodes: usize,
137139
/// Priority queue of pending events that have yet to be processed (min-heap by tick).
138140
pending_events: BinaryHeap<TimedEvent>,
139141
/// Current simulation tick.
@@ -178,12 +180,16 @@ impl DiscreteEventSimulation {
178180
TimeoutsConfig::default(),
179181
);
180182

183+
let quorum_threshold = (2 * total_nodes / 3) + 1;
184+
181185
Self {
182186
rng,
183187
seed,
188+
total_nodes,
189+
honest_nodes,
190+
quorum_threshold,
184191
shc,
185192
validators,
186-
honest_nodes,
187193
pending_events: BinaryHeap::new(),
188194
current_tick: 0,
189195
processed_history: Vec::new(),
@@ -219,17 +225,17 @@ impl DiscreteEventSimulation {
219225
/// Other nodes share the remaining probability (1 - NODE_0_LEADER_PROBABILITY) uniformly.
220226
/// The selection is deterministic per round - the same round will always return the same
221227
/// leader index.
222-
fn get_leader_index(seed: u64, round: Round) -> usize {
228+
fn get_leader_index(&self, round: Round) -> usize {
223229
let round_u64 = u64::from(round);
224-
let round_seed = seed.wrapping_mul(31).wrapping_add(round_u64);
230+
let round_seed = self.seed.wrapping_mul(31).wrapping_add(round_u64);
225231
let mut round_rng = StdRng::seed_from_u64(round_seed);
226232

227233
let random_value: f64 = round_rng.gen();
228234

229235
if random_value < NODE_0_LEADER_PROBABILITY {
230236
NODE_UNDER_TEST
231237
} else {
232-
round_rng.gen_range(1..TOTAL_NODES)
238+
round_rng.gen_range(1..self.total_nodes)
233239
}
234240
}
235241

@@ -292,7 +298,7 @@ impl DiscreteEventSimulation {
292298
fn pre_generate_all_rounds(&mut self) {
293299
for round_idx in 0..self.num_rounds {
294300
let round = Round::from(u32::try_from(round_idx).unwrap());
295-
let leader_idx = Self::get_leader_index(self.seed, round);
301+
let leader_idx = self.get_leader_index(round);
296302
let leader_id = self.validators[leader_idx];
297303
// Track rounds where NODE_0 is the proposer.
298304
// We will schedule peer votes for these rounds after the build finish event.
@@ -415,7 +421,7 @@ impl DiscreteEventSimulation {
415421
}
416422
FaultType::NonValidator => {
417423
// Send votes with a voter ID that is outside the validator set
418-
let non_validator_id = ValidatorId::from(u64::try_from(TOTAL_NODES).unwrap());
424+
let non_validator_id = ValidatorId::from(u64::try_from(self.total_nodes).unwrap());
419425
self.schedule_prevote_and_precommit(
420426
non_validator_id,
421427
round,
@@ -468,8 +474,17 @@ impl DiscreteEventSimulation {
468474

469475
let validators = self.validators.clone();
470476
let seed = self.seed;
477+
let total_nodes = self.total_nodes;
471478
let leader_fn = move |r: Round| {
472-
let idx = Self::get_leader_index(seed, r);
479+
let round_u64 = u64::from(r);
480+
let round_seed = seed.wrapping_mul(31).wrapping_add(round_u64);
481+
let mut round_rng = StdRng::seed_from_u64(round_seed);
482+
let random_value: f64 = round_rng.gen();
483+
let idx = if random_value < NODE_0_LEADER_PROBABILITY {
484+
NODE_UNDER_TEST
485+
} else {
486+
round_rng.gen_range(1..total_nodes)
487+
};
473488
validators[idx]
474489
};
475490

@@ -613,7 +628,7 @@ fn verify_result(sim: &DiscreteEventSimulation, result: Option<&Decision>) {
613628
});
614629
let total_precommits = peer_precommits + self_vote;
615630

616-
if total_precommits >= THRESHOLD {
631+
if total_precommits >= sim.quorum_threshold {
617632
Some((*r, *commitment, precommits.clone()))
618633
} else {
619634
None
@@ -667,10 +682,10 @@ fn verify_result(sim: &DiscreteEventSimulation, result: Option<&Decision>) {
667682

668683
// Verify quorum threshold is met
669684
assert!(
670-
actual.precommits.len() >= THRESHOLD,
685+
actual.precommits.len() >= sim.quorum_threshold,
671686
"Insufficient precommits in decision: {}/{}. Decision: {:?}, History: {:?}",
672687
actual.precommits.len(),
673-
THRESHOLD,
688+
sim.quorum_threshold,
674689
actual,
675690
sim.processed_history
676691
);
@@ -696,13 +711,14 @@ fn verify_result(sim: &DiscreteEventSimulation, result: Option<&Decision>) {
696711
fn test_consensus_simulation(keep_ratio: f64, honest_nodes: usize) {
697712
let seed = rand::thread_rng().gen();
698713
let num_rounds = 5; // Number of rounds to pre-generate
714+
let total_nodes = 100;
699715
println!(
700-
"Running consensus simulation with total nodes {TOTAL_NODES}, {num_rounds} rounds, keep \
716+
"Running consensus simulation with total nodes {total_nodes}, {num_rounds} rounds, keep \
701717
ratio {keep_ratio}, honest nodes {honest_nodes} and seed: {seed}"
702718
);
703719

704720
let mut sim =
705-
DiscreteEventSimulation::new(TOTAL_NODES, honest_nodes, seed, num_rounds, keep_ratio);
721+
DiscreteEventSimulation::new(total_nodes, honest_nodes, seed, num_rounds, keep_ratio);
706722

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

0 commit comments

Comments
 (0)