@@ -66,12 +66,24 @@ impl ConsensusConfig {
6666 ConsensusConfig :: from ( NetworkType :: Gossipsub )
6767 }
6868
69- pub fn set_up_rounds ( & mut self , max_rounds : u32 ) -> Result < ( ) , ConsensusError > {
70- if max_rounds == 0 {
71- return Err ( ConsensusError :: InvalidMaxRounds ) ;
72- }
73- self . max_rounds = max_rounds;
74- Ok ( ( ) )
69+ /// Set consensus timeout (validated) and return the updated config.
70+ pub fn with_timeout ( mut self , consensus_timeout : Duration ) -> Result < Self , ConsensusError > {
71+ crate :: utils:: validate_timeout ( consensus_timeout) ?;
72+ self . consensus_timeout = consensus_timeout;
73+ Ok ( self )
74+ }
75+
76+ /// Set consensus threshold (validated) and return the updated config.
77+ pub fn with_threshold ( mut self , consensus_threshold : f64 ) -> Result < Self , ConsensusError > {
78+ crate :: utils:: validate_threshold ( consensus_threshold) ?;
79+ self . consensus_threshold = consensus_threshold;
80+ Ok ( self )
81+ }
82+
83+ /// Set liveness criteria and return the updated config.
84+ pub fn with_liveness_criteria ( mut self , liveness_criteria : bool ) -> Self {
85+ self . liveness_criteria = liveness_criteria;
86+ self
7587 }
7688
7789 /// Create a new ConsensusConfig with the given values.
@@ -381,8 +393,7 @@ mod tests {
381393 . unwrap ( ) ;
382394
383395 let proposal = request. into_proposal ( ) . unwrap ( ) ;
384- let mut config = ConsensusConfig :: gossipsub ( ) ;
385- config. set_up_rounds ( 2 ) . unwrap ( ) ;
396+ let config = ConsensusConfig :: gossipsub ( ) ;
386397 let mut session = ConsensusSession :: new ( proposal, config) ;
387398
388399 // Round 1 -> Round 2 (first vote)
@@ -409,12 +420,14 @@ mod tests {
409420
410421 #[ tokio:: test]
411422 async fn enforce_max_rounds_p2p ( ) {
412- // P2P: max_rounds = 2 means maximum 2 votes
413- // Round 1 = 0 votes, Round 2 = 1 vote, Round 3 = 2 votes
414- // So max_rounds = 2 allows up to round 3 (2 votes)
423+ // P2P defaults : max_rounds = 0 triggers dynamic calculation based on expected voters.
424+ // For threshold=2/3 and expected_voters=5, max_round_limit = ceil(2n/3) = 4 votes.
425+ // Round 1 = 0 votes, Round 2 = 1 vote, ... Round 5 = 4 votes.
415426 let signer1 = PrivateKeySigner :: random ( ) ;
416427 let signer2 = PrivateKeySigner :: random ( ) ;
417428 let signer3 = PrivateKeySigner :: random ( ) ;
429+ let signer4 = PrivateKeySigner :: random ( ) ;
430+ let signer5 = PrivateKeySigner :: random ( ) ;
418431
419432 let request = CreateProposalRequest :: new (
420433 "Test" . into ( ) ,
@@ -427,8 +440,7 @@ mod tests {
427440 . unwrap ( ) ;
428441
429442 let proposal = request. into_proposal ( ) . unwrap ( ) ;
430- let mut config = ConsensusConfig :: p2p ( ) ;
431- config. set_up_rounds ( 2 ) . unwrap ( ) ;
443+ let config = ConsensusConfig :: p2p ( ) ;
432444 let mut session = ConsensusSession :: new ( proposal, config) ;
433445
434446 // Round 1 -> Round 2 (first vote, 1 vote total)
@@ -443,9 +455,21 @@ mod tests {
443455 assert_eq ! ( session. proposal. round, 3 ) ;
444456 assert_eq ! ( session. votes. len( ) , 2 ) ;
445457
446- // Third vote would be round 4 (3 votes total), which exceeds max_rounds = 2
458+ // Round 3 -> Round 4 (third vote, 3 votes total) - should succeed
447459 let vote3 = build_vote ( & session. proposal , true , signer3) . await . unwrap ( ) ;
448- let err = session. add_vote ( vote3) . unwrap_err ( ) ;
460+ session. add_vote ( vote3) . unwrap ( ) ;
461+ assert_eq ! ( session. proposal. round, 4 ) ;
462+ assert_eq ! ( session. votes. len( ) , 3 ) ;
463+
464+ // Round 4 -> Round 5 (fourth vote, 4 votes total) - should succeed (dynamic limit = 4)
465+ let vote4 = build_vote ( & session. proposal , true , signer4) . await . unwrap ( ) ;
466+ session. add_vote ( vote4) . unwrap ( ) ;
467+ assert_eq ! ( session. proposal. round, 5 ) ;
468+ assert_eq ! ( session. votes. len( ) , 4 ) ;
469+
470+ // Fifth vote would exceed dynamic max_round_limit (=4 votes)
471+ let vote5 = build_vote ( & session. proposal , true , signer5) . await . unwrap ( ) ;
472+ let err = session. add_vote ( vote5) . unwrap_err ( ) ;
449473 assert ! ( matches!( err, ConsensusError :: MaxRoundsExceeded ) ) ;
450474 }
451475}
0 commit comments