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