solana_program/vote/
authorized_voters.rs1#[cfg(test)]
2use arbitrary::Arbitrary;
3use {
4 crate::pubkey::Pubkey,
5 serde_derive::{Deserialize, Serialize},
6 solana_clock::Epoch,
7 std::collections::BTreeMap,
8};
9
10#[cfg_attr(feature = "frozen-abi", derive(AbiExample))]
11#[derive(Debug, Default, Serialize, Deserialize, PartialEq, Eq, Clone)]
12#[cfg_attr(test, derive(Arbitrary))]
13pub struct AuthorizedVoters {
14 authorized_voters: BTreeMap<Epoch, Pubkey>,
15}
16
17impl AuthorizedVoters {
18 pub fn new(epoch: Epoch, pubkey: Pubkey) -> Self {
19 let mut authorized_voters = BTreeMap::new();
20 authorized_voters.insert(epoch, pubkey);
21 Self { authorized_voters }
22 }
23
24 pub fn get_authorized_voter(&self, epoch: Epoch) -> Option<Pubkey> {
25 self.get_or_calculate_authorized_voter_for_epoch(epoch)
26 .map(|(pubkey, _)| pubkey)
27 }
28
29 pub fn get_and_cache_authorized_voter_for_epoch(&mut self, epoch: Epoch) -> Option<Pubkey> {
30 let res = self.get_or_calculate_authorized_voter_for_epoch(epoch);
31
32 res.map(|(pubkey, existed)| {
33 if !existed {
34 self.authorized_voters.insert(epoch, pubkey);
35 }
36 pubkey
37 })
38 }
39
40 pub fn insert(&mut self, epoch: Epoch, authorized_voter: Pubkey) {
41 self.authorized_voters.insert(epoch, authorized_voter);
42 }
43
44 pub fn purge_authorized_voters(&mut self, current_epoch: Epoch) -> bool {
45 let expired_keys: Vec<_> = self
48 .authorized_voters
49 .range(0..current_epoch)
50 .map(|(authorized_epoch, _)| *authorized_epoch)
51 .collect();
52
53 for key in expired_keys {
54 self.authorized_voters.remove(&key);
55 }
56
57 assert!(!self.authorized_voters.is_empty());
62 true
63 }
64
65 pub fn is_empty(&self) -> bool {
66 self.authorized_voters.is_empty()
67 }
68
69 pub fn first(&self) -> Option<(&u64, &Pubkey)> {
70 self.authorized_voters.iter().next()
71 }
72
73 pub fn last(&self) -> Option<(&u64, &Pubkey)> {
74 self.authorized_voters.iter().next_back()
75 }
76
77 pub fn len(&self) -> usize {
78 self.authorized_voters.len()
79 }
80
81 pub fn contains(&self, epoch: Epoch) -> bool {
82 self.authorized_voters.contains_key(&epoch)
83 }
84
85 pub fn iter(&self) -> std::collections::btree_map::Iter<Epoch, Pubkey> {
86 self.authorized_voters.iter()
87 }
88
89 fn get_or_calculate_authorized_voter_for_epoch(&self, epoch: Epoch) -> Option<(Pubkey, bool)> {
93 let res = self.authorized_voters.get(&epoch);
94 if res.is_none() {
95 let res = self.authorized_voters.range(0..epoch).next_back();
99
100 res.map(|(_, pubkey)| (*pubkey, false))
110 } else {
111 res.map(|pubkey| (*pubkey, true))
112 }
113 }
114}