@@ -25,8 +25,6 @@ use crate::types::{Decision, ProposalCommitment, Round, ValidatorId};
2525use crate :: votes_threshold:: QuorumType ;
2626
2727const HEIGHT_0 : BlockNumber = BlockNumber ( 0 ) ;
28- const TOTAL_NODES : usize = 100 ;
29- const THRESHOLD : usize = ( 2 * TOTAL_NODES / 3 ) + 1 ;
3028const DEADLINE_TICKS : u64 = 200 ;
3129const NODE_0_LEADER_PROBABILITY : f64 = 0.1 ;
3230const 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" ) ]
613628fn 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