Skip to content

Commit c0b63ba

Browse files
apollo_consensus: use instance fields instead of constants in sim test
1 parent bc1f76f commit c0b63ba

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

298304
// Determine time range for this round
@@ -434,7 +440,7 @@ impl DiscreteEventSimulation {
434440
}
435441
FaultType::NonValidator => {
436442
// Send votes with a voter ID that is outside the validator set
437-
let non_validator_id = ValidatorId::from(u64::try_from(TOTAL_NODES).unwrap());
443+
let non_validator_id = ValidatorId::from(u64::try_from(self.total_nodes).unwrap());
438444
self.schedule_prevote_and_precommit(
439445
non_validator_id,
440446
round,
@@ -510,8 +516,17 @@ impl DiscreteEventSimulation {
510516

511517
let validators = self.validators.clone();
512518
let seed = self.seed;
519+
let total_nodes = self.total_nodes;
513520
let leader_fn = move |r: Round| {
514-
let idx = Self::get_leader_index(seed, r);
521+
let round_u64 = u64::from(r);
522+
let round_seed = seed.wrapping_mul(31).wrapping_add(round_u64);
523+
let mut round_rng = StdRng::seed_from_u64(round_seed);
524+
let random_value: f64 = round_rng.gen();
525+
let idx = if random_value < NODE_0_LEADER_PROBABILITY {
526+
NODE_UNDER_TEST
527+
} else {
528+
round_rng.gen_range(1..total_nodes)
529+
};
515530
validators[idx]
516531
};
517532

@@ -659,7 +674,7 @@ fn verify_result(sim: &DiscreteEventSimulation, result: Option<&Decision>) {
659674
});
660675
let total_precommits = peer_precommits + self_vote;
661676

662-
if total_precommits >= THRESHOLD {
677+
if total_precommits >= sim.quorum_threshold {
663678
Some((*r, *commitment, precommits.clone()))
664679
} else {
665680
None
@@ -713,10 +728,10 @@ fn verify_result(sim: &DiscreteEventSimulation, result: Option<&Decision>) {
713728

714729
// Verify quorum threshold is met
715730
assert!(
716-
actual.precommits.len() >= THRESHOLD,
731+
actual.precommits.len() >= sim.quorum_threshold,
717732
"Insufficient precommits in decision: {}/{}. Decision: {:?}, History: {:?}",
718733
actual.precommits.len(),
719-
THRESHOLD,
734+
sim.quorum_threshold,
720735
actual,
721736
sim.processed_history
722737
);
@@ -742,13 +757,14 @@ fn verify_result(sim: &DiscreteEventSimulation, result: Option<&Decision>) {
742757
fn test_consensus_simulation(keep_ratio: f64, honest_nodes: usize) {
743758
let seed = rand::thread_rng().gen();
744759
let num_rounds = 5; // Number of rounds to pre-generate
760+
let total_nodes = 100;
745761
println!(
746-
"Running consensus simulation with total nodes {TOTAL_NODES}, {num_rounds} rounds, keep \
762+
"Running consensus simulation with total nodes {total_nodes}, {num_rounds} rounds, keep \
747763
ratio {keep_ratio}, honest nodes {honest_nodes} and seed: {seed}"
748764
);
749765

750766
let mut sim =
751-
DiscreteEventSimulation::new(TOTAL_NODES, honest_nodes, seed, num_rounds, keep_ratio);
767+
DiscreteEventSimulation::new(total_nodes, honest_nodes, seed, num_rounds, keep_ratio);
752768

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

0 commit comments

Comments
 (0)