Skip to main content

bad_addresses/
lib.rs

1#![no_std]
2extern crate alloc;
3use alloc::collections::BTreeMap; // replace with HashMap if std is allowed
4use alloc::vec::Vec;
5
6use solana_sdk::{clock::Slot, pubkey::Pubkey};
7
8pub const MAX_ADDRESSES: usize = 512;
9
10pub mod sysvar;
11
12#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
13pub struct BadAddresses {
14    map: BTreeMap<Pubkey, Slot>,
15}
16
17impl Default for BadAddresses {
18    fn default() -> Self {
19        Self {
20            map: BTreeMap::new(),
21        }
22    }
23}
24
25impl BadAddresses {
26    pub fn insert(&mut self, address: Pubkey, slot: Slot) {
27        if self.map.len() >= MAX_ADDRESSES && !self.map.contains_key(&address) {
28            // Evict the oldest (lowest slot)
29            if let Some((oldest_key, _)) = self
30                .map
31                .iter()
32                .min_by_key(|(_, s)| *s)
33                .map(|(k, _)| (k.clone(), ()))
34            {
35                self.map.remove(&oldest_key);
36            }
37        }
38        self.map.insert(address, slot);
39    }
40
41    pub fn contains(&self, address: &Pubkey) -> bool {
42        self.map.contains_key(address)
43    }
44
45    pub fn get_slot(&self, address: &Pubkey) -> Option<Slot> {
46        self.map.get(address).cloned()
47    }
48
49    pub fn len(&self) -> usize {
50        self.map.len()
51    }
52
53    pub fn size_hint() -> usize {
54        // Estimate: 32 (Pubkey) + 8 (Slot) per entry
55        MAX_ADDRESSES * (32 + 8) + 8
56    }
57}