Skip to content

Commit 47060a2

Browse files
apollo_consensus: use instance fields instead of constants in sim test
1 parent 4e25987 commit 47060a2

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 DEADLINE_TICKS: u64 = 200;
3129
const NODE_0_LEADER_PROBABILITY: f64 = 0.1;
3230
const NODE_UNDER_TEST: usize = 0;
@@ -110,12 +108,16 @@ struct DiscreteEventSimulation {
110108
rng: StdRng,
111109
/// The seed used to initialize the simulation.
112110
seed: u64,
111+
/// Total number of nodes in the network.
112+
total_nodes: usize,
113+
/// Number of honest nodes (the rest are faulty).
114+
honest_nodes: usize,
115+
/// Quorum threshold for reaching consensus (2/3 + 1 of total nodes).
116+
quorum_threshold: usize,
113117
/// The single height consensus instance.
114118
shc: SingleHeightConsensus,
115119
/// All validators in the network.
116120
validators: Vec<ValidatorId>,
117-
/// Number of honest nodes (the rest are faulty).
118-
honest_nodes: usize,
119121
/// The current maximum round being processed.
120122
current_max_round: Option<Round>,
121123
/// Priority queue of pending events that have yet to be processed (min-heap by tick).
@@ -155,12 +157,16 @@ impl DiscreteEventSimulation {
155157
TimeoutsConfig::default(),
156158
);
157159

160+
let quorum_threshold = (2 * total_nodes / 3) + 1;
161+
158162
Self {
159163
rng,
160164
seed,
165+
total_nodes,
166+
honest_nodes,
167+
quorum_threshold,
161168
shc,
162169
validators,
163-
honest_nodes,
164170
current_max_round: None,
165171
pending_events: BinaryHeap::new(),
166172
current_tick: 0,
@@ -196,17 +202,17 @@ impl DiscreteEventSimulation {
196202
/// Other nodes share the remaining probability (1 - NODE_0_LEADER_PROBABILITY) uniformly.
197203
/// The selection is deterministic per round - the same round will always return the same
198204
/// leader index.
199-
fn get_leader_index(seed: u64, round: Round) -> usize {
205+
fn get_leader_index(&self, round: Round) -> usize {
200206
let round_u64 = u64::from(round);
201-
let round_seed = seed.wrapping_mul(31).wrapping_add(round_u64);
207+
let round_seed = self.seed.wrapping_mul(31).wrapping_add(round_u64);
202208
let mut round_rng = StdRng::seed_from_u64(round_seed);
203209

204210
let random_value: f64 = round_rng.gen();
205211

206212
if random_value < NODE_0_LEADER_PROBABILITY {
207213
NODE_UNDER_TEST
208214
} else {
209-
round_rng.gen_range(1..TOTAL_NODES)
215+
round_rng.gen_range(1..self.total_nodes)
210216
}
211217
}
212218

@@ -273,7 +279,7 @@ impl DiscreteEventSimulation {
273279
///
274280
/// Honest nodes behave correctly, while faulty nodes exhibit various fault behaviors.
275281
fn generate_round_traffic(&mut self, round: Round) {
276-
let leader_idx = Self::get_leader_index(self.seed, round);
282+
let leader_idx = self.get_leader_index(round);
277283
let leader_id = self.validators[leader_idx];
278284
let proposal_commitment = Some(proposal_commitment_for_round(round, false));
279285

@@ -341,7 +347,7 @@ impl DiscreteEventSimulation {
341347
}
342348
FaultType::NonValidator => {
343349
// Send votes with a voter ID that is outside the validator set
344-
let non_validator_id = ValidatorId::from(u64::try_from(TOTAL_NODES).unwrap());
350+
let non_validator_id = ValidatorId::from(u64::try_from(self.total_nodes).unwrap());
345351
self.schedule_prevote_and_precommit(non_validator_id, round, proposal_commitment);
346352
}
347353
}
@@ -395,8 +401,17 @@ impl DiscreteEventSimulation {
395401
fn run(&mut self, deadline_ticks: u64) -> Option<Decision> {
396402
let validators = self.validators.clone();
397403
let seed = self.seed;
404+
let total_nodes = self.total_nodes;
398405
let leader_fn = move |r: Round| {
399-
let idx = Self::get_leader_index(seed, r);
406+
let round_u64 = u64::from(r);
407+
let round_seed = seed.wrapping_mul(31).wrapping_add(round_u64);
408+
let mut round_rng = StdRng::seed_from_u64(round_seed);
409+
let random_value: f64 = round_rng.gen();
410+
let idx = if random_value < NODE_0_LEADER_PROBABILITY {
411+
NODE_UNDER_TEST
412+
} else {
413+
round_rng.gen_range(1..total_nodes)
414+
};
400415
validators[idx]
401416
};
402417

@@ -530,7 +545,7 @@ fn verify_result(sim: &DiscreteEventSimulation, result: Option<&Decision>) {
530545
});
531546
let total_precommits = peer_precommits + self_vote;
532547

533-
if total_precommits >= THRESHOLD {
548+
if total_precommits >= sim.quorum_threshold {
534549
Some((*r, *commitment, precommits.clone()))
535550
} else {
536551
None
@@ -584,10 +599,10 @@ fn verify_result(sim: &DiscreteEventSimulation, result: Option<&Decision>) {
584599

585600
// Verify quorum threshold is met
586601
assert!(
587-
actual.precommits.len() >= THRESHOLD,
602+
actual.precommits.len() >= sim.quorum_threshold,
588603
"Insufficient precommits in decision: {}/{}. Decision: {:?}, History: {:?}",
589604
actual.precommits.len(),
590-
THRESHOLD,
605+
sim.quorum_threshold,
591606
actual,
592607
sim.processed_history
593608
);
@@ -612,12 +627,13 @@ fn verify_result(sim: &DiscreteEventSimulation, result: Option<&Decision>) {
612627
#[test_case(0.9, 80; "keep_90%_80_honest")]
613628
fn test_consensus_simulation(keep_ratio: f64, honest_nodes: usize) {
614629
let seed = rand::thread_rng().gen();
630+
let total_nodes = 100;
615631
println!(
616-
"Running consensus simulation with total nodes {TOTAL_NODES}, keep ratio {keep_ratio}, \
632+
"Running consensus simulation with total nodes {total_nodes}, keep ratio {keep_ratio}, \
617633
honest nodes {honest_nodes} and seed: {seed}"
618634
);
619635

620-
let mut sim = DiscreteEventSimulation::new(TOTAL_NODES, honest_nodes, seed, keep_ratio);
636+
let mut sim = DiscreteEventSimulation::new(total_nodes, honest_nodes, seed, keep_ratio);
621637

622638
let result = sim.run(DEADLINE_TICKS);
623639

0 commit comments

Comments
 (0)