@@ -224,12 +224,11 @@ fn test_node_recovery() {
224224 assert_eq ! ( num_consensus, 5 ) ; // Should reach full consensus after recovery
225225}
226226
227- /// Test that FAILS if round change validation doesn't require prepare justifications for
228- /// data_round=1
227+ /// Test round change validation consistency for data_round=1 scenarios
229228///
230- /// This test creates a proposal with round change messages claiming preparation in round 1
231- /// (data_round=1) but provides NO prepare justifications.
232- /// The test FAILS if the validation doesn't reject the proposal as it should .
229+ /// This test verifies that proposals with round change messages claiming preparation in round 1
230+ /// (data_round=1) are properly validated against their prepare justifications.
231+ /// The test ensures consistent validation behavior across all data_round values .
233232#[ test]
234233fn test_round_change_validation_skips_round_one_prepared_values ( ) {
235234 if ENABLE_TEST_LOGGING {
@@ -264,19 +263,19 @@ fn test_round_change_validation_skips_round_one_prepared_values() {
264263 |_| { } ,
265264 ) ;
266265
267- // Create a MALICIOUS round change message:
266+ // Create a round change message that tests edge case behavior :
268267 // - Claims to have prepared a value in round 1 (data_round = 1)
269268 // - But provides NO prepare justifications (empty prepare_justification)
270- // This should be REJECTED but the bug allows it through
269+ // This tests whether validation is consistent across all data_round values
271270 let malicious_round_change = QbftMessage {
272271 qbft_message_type : QbftMessageType :: RoundChange ,
273272 height : 0 ,
274273 round : 2 ,
275274 identifier : [ 0 ; 56 ] . to_vec ( ) . into ( ) ,
276275 root : test_data. hash ( ) ,
277- data_round : 1 , // Claims preparation in round 1 - this is the bug trigger!
276+ data_round : 1 , // Claims preparation in round 1 - edge case to test
278277 round_change_justification : vec ! [ ] ,
279- prepare_justification : vec ! [ ] , // INVALID: No justifications for claimed preparation!
278+ prepare_justification : vec ! [ ] , // No justifications provided for claimed preparation
280279 } ;
281280
282281 // Create signed round change messages (need quorum of 3 for 3-node committee)
@@ -333,27 +332,27 @@ fn test_round_change_validation_skips_round_one_prepared_values() {
333332 qbft_message : proposal,
334333 } ;
335334
336- // Call the actual buggy validation function
335+ // Call the validation function to test behavior
337336 let validation_result = qbft_instance. validate_proposal_justifications ( & wrapped_proposal) ;
338337
339338 // The validation should REJECT this proposal because:
340339 // - Round change messages claim data_round=1 (prepared in round 1)
341340 // - But they provide NO prepare justifications to prove this claim
342341
343342 println ! (
344- "Validation result for malicious proposal: {}" ,
343+ "Validation result for test proposal: {}" ,
345344 validation_result
346345 ) ;
347346 println ! ( "This proposal should be REJECTED because round change messages" ) ;
348347 println ! ( "claim preparation in round 1 but provide no prepare justifications." ) ;
349348
350- // This assertion will FAIL if a buggy code returns true (accepts invalid proposal)
349+ // This assertion ensures consistent validation behavior across all data_round values
351350 assert ! (
352351 !validation_result,
353- "BUG : validate_justifications() accepted an invalid proposal! \
354- Round change messages claim data_round=1 (prepared in round 1) but provide no \
355- prepare justifications. This should be rejected but the validation logic \
356- incorrectly skips prepare justification checking for round 1 preparations ."
352+ "Validation inconsistency : validate_justifications() accepted a proposal \
353+ where round change messages claim data_round=1 (prepared in round 1) but provide no \
354+ prepare justifications. Validation should be consistent and require justifications \
355+ for all claimed preparations regardless of data_round value ."
357356 ) ;
358357}
359358
@@ -452,17 +451,17 @@ fn test_round_change_acceptance(
452451 }
453452}
454453
455- /// Test that verifies QBFT rejects round change messages with invalid justification patterns
454+ /// Test that verifies QBFT rejects round change messages with inconsistent justification patterns
456455///
457- /// This test verifies the fix for a critical consensus vulnerability where malicious nodes
458- /// could include unvalidated prepare messages in round changes claiming no preparation .
456+ /// This test verifies proper validation of round change messages to ensure consistency
457+ /// between claimed preparation state and provided justifications .
459458///
460- /// Security validation requirements implemented in this codebase:
459+ /// Validation requirements implemented in this codebase:
461460/// - If data_round == 0 (no preparation claimed): No prepare justifications should be present
462461/// - If data_round > 0 (preparation claimed): Prepare justifications MUST be validated
463462///
464- /// This prevents malicious nodes from injecting unvalidated prepare messages that bypass
465- /// consensus safety checks by claiming no preparation while including justifications .
463+ /// This ensures consistent validation behavior and prevents inconsistent message patterns
464+ /// that could affect consensus reliability .
466465#[ test]
467466fn test_round_change_justification_validation_vulnerability_fix ( ) {
468467 if ENABLE_TEST_LOGGING {
@@ -497,9 +496,9 @@ fn test_round_change_justification_validation_vulnerability_fix() {
497496 // Advance to round 2 for testing
498497 qbft_instance. current_round = Round :: from ( 2 ) ;
499498
500- println ! ( "Testing vulnerability fix for round change justification validation..." ) ;
499+ println ! ( "Testing round change justification validation consistency ..." ) ;
501500
502- // Create a malicious prepare message to use as justification
501+ // Create a prepare message to use as justification in test scenarios
503502 let malicious_prepare = QbftMessage {
504503 qbft_message_type : QbftMessageType :: Prepare ,
505504 height : 0 ,
@@ -510,20 +509,20 @@ fn test_round_change_justification_validation_vulnerability_fix() {
510509 round_change_justification : vec ! [ ] ,
511510 prepare_justification : vec ! [ ] ,
512511 } ;
513- let signed_malicious_prepare =
512+ let signed_test_prepare =
514513 create_signed_ssv_message ( malicious_prepare, OperatorId :: from ( 2 ) , vec ! [ ] ) ;
515514
516- // TEST 1: Malicious round change with data_round=0 but includes prepare justifications
515+ // TEST 1: Inconsistent round change with data_round=0 but includes prepare justifications
517516 println ! ( "TEST 1: Round change with data_round=0 but includes prepare justifications" ) ;
518- let malicious_round_change = create_wrapped_round_change (
517+ let inconsistent_round_change = create_wrapped_round_change (
519518 0 , // data_round = 0 (claims no preparation)
520519 2 ,
521- vec ! [ signed_malicious_prepare ] , // BUT includes justifications!
520+ vec ! [ signed_test_prepare ] , // BUT includes justifications!
522521 OperatorId :: from ( 2 ) ,
523522 ) ;
524523 test_round_change_acceptance (
525524 & mut qbft_instance,
526- malicious_round_change ,
525+ inconsistent_round_change ,
527526 OperatorId :: from ( 2 ) ,
528527 Round :: from ( 2 ) ,
529528 false , // should be rejected
@@ -547,12 +546,12 @@ fn test_round_change_justification_validation_vulnerability_fix() {
547546 "TEST 2" ,
548547 ) ;
549548
550- println ! ( "SUCCESS: QBFT round change justification validation vulnerability has been fixed !" ) ;
549+ println ! ( "SUCCESS: QBFT round change justification validation is working correctly !" ) ;
551550 println ! (
552- "- Malicious round changes with data_round=0 but non-empty justifications are rejected"
551+ "- Inconsistent round changes with data_round=0 but non-empty justifications are rejected"
553552 ) ;
554553 println ! ( "- Valid round changes with data_round=0 and empty justifications are accepted" ) ;
555554 println ! (
556- "- This prevents consensus safety violations from unvalidated prepare message injection "
555+ "- This ensures consistent validation behavior and consensus reliability "
557556 ) ;
558557}
0 commit comments