use std::collections::BTreeMap;
use crate::pubkey::Pubkey;
#[derive(Default, Serialize, Deserialize, Debug, PartialEq, Eq, Clone, Copy)]
pub struct VoteInit {
node_pubkey: Pubkey,
node_pubkey_parity_even: bool,
authority: Pubkey,
commission: u8,
}
impl VoteInit {
pub fn new(
node_pubkey: Pubkey,
node_pubkey_parity_even: bool,
authority: Pubkey,
commission: u8,
) -> Self {
Self {
node_pubkey,
node_pubkey_parity_even,
authority,
commission,
}
}
pub const fn size_of() -> usize {
32 + 1 + 32 + 32 + 1
}
}
#[derive(Default, Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
pub struct VoteState {
pub node_pubkey: Pubkey,
pub node_pubkey_parity_even: bool,
pub authority: Pubkey,
pub commission: u8,
}
impl VoteState {
pub fn new(vote_init: &VoteInit) -> Self {
Self {
node_pubkey: vote_init.node_pubkey,
node_pubkey_parity_even: vote_init.node_pubkey_parity_even,
authority: vote_init.authority,
commission: vote_init.commission,
}
}
pub const fn size_of_new() -> usize {
32 + 1 + 32 + 1
}
pub fn serialize(&self) -> Vec<u8> {
bincode::serialize(self).unwrap()
}
pub fn deserialize(data: &[u8]) -> Self {
bincode::deserialize(data).unwrap()
}
pub fn node_pubkey_serialized(&self) -> [u8; 33] {
let mut ret = [0_u8; 33];
if self.node_pubkey_parity_even {
ret[0] = 0x02;
} else {
ret[0] = 0x03;
}
ret[1..].copy_from_slice(&self.node_pubkey.serialize()[..]);
ret
}
}
#[derive(Debug, Default, Serialize, Deserialize, PartialEq, Eq, Clone)]
pub struct AuthorizedVoters {
authorized_voters: BTreeMap<u64, Pubkey>,
}
impl AuthorizedVoters {
pub fn new(epoch: u64, pubkey: Pubkey) -> Self {
let mut authorized_voters = BTreeMap::new();
authorized_voters.insert(epoch, pubkey);
Self { authorized_voters }
}
pub fn get_authorized_voter(&self, epoch: u64) -> Option<Pubkey> {
self.get_or_calculate_authorized_voter_for_epoch(epoch)
.map(|(pubkey, _)| pubkey)
}
pub fn get_and_cache_authorized_voter_for_epoch(&mut self, epoch: u64) -> Option<Pubkey> {
let res = self.get_or_calculate_authorized_voter_for_epoch(epoch);
res.map(|(pubkey, existed)| {
if !existed {
self.authorized_voters.insert(epoch, pubkey);
}
pubkey
})
}
pub fn insert(&mut self, epoch: u64, authorized_voter: Pubkey) {
self.authorized_voters.insert(epoch, authorized_voter);
}
pub fn purge_authorized_voters(&mut self, current_epoch: u64) -> bool {
let expired_keys: Vec<_> = self
.authorized_voters
.range(0..current_epoch)
.map(|(authorized_epoch, _)| *authorized_epoch)
.collect();
for key in expired_keys {
self.authorized_voters.remove(&key);
}
assert!(!self.authorized_voters.is_empty());
true
}
pub fn is_empty(&self) -> bool {
self.authorized_voters.is_empty()
}
pub fn first(&self) -> Option<(&u64, &Pubkey)> {
self.authorized_voters.iter().next()
}
pub fn last(&self) -> Option<(&u64, &Pubkey)> {
self.authorized_voters.iter().next_back()
}
pub fn len(&self) -> usize {
self.authorized_voters.len()
}
pub fn contains(&self, epoch: u64) -> bool {
self.authorized_voters.contains_key(&epoch)
}
pub fn iter(&self) -> std::collections::btree_map::Iter<'_, u64, Pubkey> {
self.authorized_voters.iter()
}
fn get_or_calculate_authorized_voter_for_epoch(&self, epoch: u64) -> Option<(Pubkey, bool)> {
let res = self.authorized_voters.get(&epoch);
if res.is_none() {
let res = self.authorized_voters.range(0..epoch).next_back();
res.map(|(_, pubkey)| (*pubkey, false))
} else {
res.map(|pubkey| (*pubkey, true))
}
}
}