1use std::sync::Mutex;
4
5use bloom::{BloomFilter, ASMS};
6
7mod constants {
8 pub const EXPECTED_NUM_ITEMS: u32 = 1_000_000;
9}
10
11struct Bloom {
12 filters: [BloomFilter; 2],
13 current: usize,
14 count: u32,
15}
16
17impl Bloom {
18 fn new() -> Self {
19 Bloom {
20 filters: [
21 BloomFilter::with_rate(1e-6, constants::EXPECTED_NUM_ITEMS),
22 BloomFilter::with_rate(1e-6, constants::EXPECTED_NUM_ITEMS),
23 ],
24 current: 0,
25 count: 0,
26 }
27 }
28
29 fn check_and_insert(&mut self, element: &[u8]) -> bool {
30 if self.filters.iter().any(|x| x.contains(&element)) {
31 return false;
32 }
33
34 let filter = &mut self.filters[self.current];
35 filter.insert(&element);
36
37 self.count += 1;
38 if self.count == constants::EXPECTED_NUM_ITEMS {
39 self.current = (self.current + 1) % 2;
40 self.filters[self.current].clear();
41 }
42
43 true
44 }
45}
46
47pub struct ReplayProtection {
49 bloom: Mutex<Bloom>,
50}
51
52impl ReplayProtection {
53 pub fn new() -> Self {
55 ReplayProtection {
56 bloom: Mutex::new(Bloom::new()),
57 }
58 }
59
60 pub fn check_and_insert(&self, element: &[u8]) -> bool {
67 self.bloom.lock().unwrap().check_and_insert(&element)
68 }
69}