Skip to content

Commit feb7171

Browse files
authored
test: add BLS signature failure tests to eth2-client (#954)
Add comprehensive test coverage for invalid BLS signatures including: - Corrupted signature bytes - Zero/invalid signature format - Mismatched sync committee bits - Wrong attested header causing signature verification failure
1 parent 22f3db8 commit feb7171

File tree

1 file changed

+80
-0
lines changed

1 file changed

+80
-0
lines changed

contracts/near/eth2-client/src/tests/unit_tests.rs

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,86 @@ mod tests {
460460
update.sync_committee_update = None;
461461
contract.submit_beacon_chain_light_client_update(update);
462462
}
463+
464+
#[test]
465+
#[should_panic(expected = "BLS12381InvalidInput")]
466+
pub fn test_panic_on_invalid_bls_signature() {
467+
let TestContext {
468+
mut contract,
469+
headers: _,
470+
updates,
471+
} = get_test_context(None);
472+
set_env!(prepaid_gas: Gas::from_tgas(1_000_000), predecessor_account_id: accounts(0));
473+
let mut update = updates[1].clone();
474+
475+
// Corrupt the BLS signature by modifying the last byte
476+
let mut signature_bytes = update.sync_aggregate.sync_committee_signature.0.to_vec();
477+
let last_idx = signature_bytes.len() - 1;
478+
signature_bytes[last_idx] = signature_bytes[last_idx].wrapping_add(1);
479+
update.sync_aggregate.sync_committee_signature = signature_bytes.into();
480+
481+
contract.submit_beacon_chain_light_client_update(update);
482+
}
483+
484+
#[test]
485+
#[should_panic(expected = "Failed to verify the bls signature")]
486+
pub fn test_panic_on_mismatched_sync_committee_bits() {
487+
let TestContext {
488+
mut contract,
489+
headers: _,
490+
updates,
491+
} = get_test_context(None);
492+
set_env!(prepaid_gas: Gas::from_tgas(1_000_000), predecessor_account_id: accounts(0));
493+
let mut update = updates[1].clone();
494+
495+
// Create a sync committee bits pattern that doesn't match the signature
496+
// but still meets the minimum participation threshold
497+
let mut sync_committee_bits = bitarr![u8, Lsb0; 0; 512];
498+
// Set exactly 342 bits (minimum required) but in different positions
499+
// than the original signature was created for
500+
for i in 0..342 {
501+
sync_committee_bits.set(i, true);
502+
}
503+
update.sync_aggregate.sync_committee_bits = sync_committee_bits.as_raw_mut_slice().to_vec().into();
504+
505+
contract.submit_beacon_chain_light_client_update(update);
506+
}
507+
508+
#[test]
509+
#[should_panic(expected = "BLS12381InvalidInput")]
510+
pub fn test_panic_on_zero_bls_signature() {
511+
let TestContext {
512+
mut contract,
513+
headers: _,
514+
updates,
515+
} = get_test_context(None);
516+
set_env!(prepaid_gas: Gas::from_tgas(1_000_000), predecessor_account_id: accounts(0));
517+
let mut update = updates[1].clone();
518+
519+
// Set signature to all zeros
520+
let signature_bytes = vec![0u8; 96];
521+
update.sync_aggregate.sync_committee_signature = signature_bytes.into();
522+
523+
contract.submit_beacon_chain_light_client_update(update);
524+
}
525+
526+
#[test]
527+
#[should_panic(expected = "Failed to verify the bls signature")]
528+
pub fn test_panic_on_wrong_attested_header() {
529+
let TestContext {
530+
mut contract,
531+
headers: _,
532+
updates,
533+
} = get_test_context(None);
534+
set_env!(prepaid_gas: Gas::from_tgas(1_000_000), predecessor_account_id: accounts(0));
535+
let mut update = updates[1].clone();
536+
537+
// Modify the attested header to make signature verification fail
538+
// but keep the signature and bits valid (so it passes format checks)
539+
update.attested_beacon_header.slot = update.attested_beacon_header.slot + 1;
540+
541+
contract.submit_beacon_chain_light_client_update(update);
542+
}
463543
}
464544

465545
#[cfg(feature = "mainnet")]

0 commit comments

Comments
 (0)