use super::{BloomFilter, Sha256};
use commonware_codec::conformance::CodecConformance;
use commonware_conformance::Conformance;
use commonware_utils::rational::BigRationalExt;
use core::num::NonZeroUsize;
use num_rational::BigRational;
commonware_conformance::conformance_tests! {
CodecConformance<BloomFilter>,
RationalOptimalBits => 1024,
}
struct RationalOptimalBits;
impl Conformance for RationalOptimalBits {
async fn commit(seed: u64) -> Vec<u8> {
let mut log = Vec::new();
let expected_items = ((seed % 1_000_000) + 1) as usize;
let fp_rates = [
BigRational::from_frac_u64(1, 10_000), BigRational::from_frac_u64(1, 1_000), BigRational::from_frac_u64(1, 100), BigRational::from_frac_u64(1, 10), ];
for fp_rate in &fp_rates {
let bits = BloomFilter::<Sha256>::optimal_bits(expected_items, fp_rate);
let hashers = BloomFilter::<Sha256>::optimal_hashers(expected_items, bits);
log.extend((expected_items as u64).to_be_bytes());
log.extend((bits as u64).to_be_bytes());
log.extend(hashers.to_be_bytes());
let filter = BloomFilter::<Sha256>::with_rate(
NonZeroUsize::new(expected_items).unwrap(),
fp_rate.clone(),
);
log.extend((filter.bits().get() as u64).to_be_bytes());
log.extend(filter.hashers().get().to_be_bytes());
}
let boundary_rates = [
BigRational::from_frac_u64(1, 7_000), BigRational::from_frac_u64(1, 500), BigRational::from_frac_u64(1, 50), BigRational::from_frac_u64(3, 100), ];
for fp_rate in &boundary_rates {
let bits = BloomFilter::<Sha256>::optimal_bits(expected_items, fp_rate);
log.extend((bits as u64).to_be_bytes());
}
log
}
}