remove hashmap from stake_history (#5834)
This commit is contained in:
parent
bdda79343e
commit
affcb5ec43
|
@ -20,10 +20,7 @@ crate::solana_name_id!(ID, "SysvarS1otHashes111111111111111111111111111");
|
||||||
pub const MAX_SLOT_HASHES: usize = 512; // 512 slots to get your vote in
|
pub const MAX_SLOT_HASHES: usize = 512; // 512 slots to get your vote in
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||||
pub struct SlotHashes {
|
pub struct SlotHashes(Vec<(Slot, Hash)>);
|
||||||
// non-pub to keep control of size
|
|
||||||
inner: Vec<(Slot, Hash)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SlotHashes {
|
impl SlotHashes {
|
||||||
pub fn from(account: &Account) -> Option<Self> {
|
pub fn from(account: &Account) -> Option<Self> {
|
||||||
|
@ -34,26 +31,30 @@ impl SlotHashes {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn size_of() -> usize {
|
pub fn size_of() -> usize {
|
||||||
serialized_size(&SlotHashes {
|
serialized_size(&SlotHashes(vec![(0, Hash::default()); MAX_SLOT_HASHES])).unwrap() as usize
|
||||||
inner: vec![(0, Hash::default()); MAX_SLOT_HASHES],
|
|
||||||
})
|
|
||||||
.unwrap() as usize
|
|
||||||
}
|
}
|
||||||
pub fn add(&mut self, slot: Slot, hash: Hash) {
|
pub fn add(&mut self, slot: Slot, hash: Hash) {
|
||||||
self.inner.insert(0, (slot, hash));
|
match self.binary_search_by(|probe| slot.cmp(&probe.0)) {
|
||||||
self.inner.truncate(MAX_SLOT_HASHES);
|
Ok(index) => (self.0)[index] = (slot, hash),
|
||||||
|
Err(index) => (self.0).insert(index, (slot, hash)),
|
||||||
|
}
|
||||||
|
(self.0).truncate(MAX_SLOT_HASHES);
|
||||||
|
}
|
||||||
|
#[allow(clippy::trivially_copy_pass_by_ref)]
|
||||||
|
pub fn get(&self, slot: &Slot) -> Option<&Hash> {
|
||||||
|
self.binary_search_by(|probe| slot.cmp(&probe.0))
|
||||||
|
.ok()
|
||||||
|
.map(|index| &self[index].1)
|
||||||
}
|
}
|
||||||
pub fn new(slot_hashes: &[(Slot, Hash)]) -> Self {
|
pub fn new(slot_hashes: &[(Slot, Hash)]) -> Self {
|
||||||
Self {
|
Self(slot_hashes.to_vec())
|
||||||
inner: slot_hashes.to_vec(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Deref for SlotHashes {
|
impl Deref for SlotHashes {
|
||||||
type Target = Vec<(u64, Hash)>;
|
type Target = Vec<(u64, Hash)>;
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
&self.inner
|
&self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,7 +84,7 @@ mod tests {
|
||||||
let account = create_account(lamports, &[]);
|
let account = create_account(lamports, &[]);
|
||||||
assert_eq!(account.data.len(), SlotHashes::size_of());
|
assert_eq!(account.data.len(), SlotHashes::size_of());
|
||||||
let slot_hashes = SlotHashes::from(&account);
|
let slot_hashes = SlotHashes::from(&account);
|
||||||
assert_eq!(slot_hashes, Some(SlotHashes { inner: vec![] }));
|
assert_eq!(slot_hashes, Some(SlotHashes(vec![])));
|
||||||
let mut slot_hashes = slot_hashes.unwrap();
|
let mut slot_hashes = slot_hashes.unwrap();
|
||||||
for i in 0..MAX_SLOT_HASHES + 1 {
|
for i in 0..MAX_SLOT_HASHES + 1 {
|
||||||
slot_hashes.add(
|
slot_hashes.add(
|
||||||
|
|
|
@ -2,13 +2,10 @@
|
||||||
//!
|
//!
|
||||||
//! this account carries history about stake activations and de-activations
|
//! this account carries history about stake activations and de-activations
|
||||||
//!
|
//!
|
||||||
use crate::account::Account;
|
|
||||||
use crate::sysvar;
|
|
||||||
use bincode::serialized_size;
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::ops::Deref;
|
|
||||||
|
|
||||||
pub use crate::clock::Epoch;
|
pub use crate::clock::Epoch;
|
||||||
|
use crate::{account::Account, sysvar};
|
||||||
|
use bincode::serialized_size;
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
const ID: [u8; 32] = [
|
const ID: [u8; 32] = [
|
||||||
6, 167, 213, 23, 25, 53, 132, 208, 254, 237, 155, 179, 67, 29, 19, 32, 107, 229, 68, 40, 27,
|
6, 167, 213, 23, 25, 53, 132, 208, 254, 237, 155, 179, 67, 29, 19, 32, 107, 229, 68, 40, 27,
|
||||||
|
@ -27,9 +24,7 @@ pub struct StakeHistoryEntry {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Default, Clone)]
|
#[derive(Debug, Serialize, Deserialize, PartialEq, Default, Clone)]
|
||||||
pub struct StakeHistory {
|
pub struct StakeHistory(Vec<(Epoch, StakeHistoryEntry)>);
|
||||||
inner: HashMap<Epoch, StakeHistoryEntry>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl StakeHistory {
|
impl StakeHistory {
|
||||||
pub fn from(account: &Account) -> Option<Self> {
|
pub fn from(account: &Account) -> Option<Self> {
|
||||||
|
@ -40,27 +35,33 @@ impl StakeHistory {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn size_of() -> usize {
|
pub fn size_of() -> usize {
|
||||||
serialized_size(
|
serialized_size(&StakeHistory(vec![
|
||||||
&(0..MAX_STAKE_HISTORY)
|
(0, StakeHistoryEntry::default());
|
||||||
.map(|i| (i as u64, StakeHistoryEntry::default()))
|
MAX_STAKE_HISTORY
|
||||||
.collect::<HashMap<_, _>>(),
|
]))
|
||||||
)
|
|
||||||
.unwrap() as usize
|
.unwrap() as usize
|
||||||
}
|
}
|
||||||
pub fn add(&mut self, epoch: Epoch, entry: StakeHistoryEntry) {
|
|
||||||
self.inner.insert(epoch, entry);
|
|
||||||
|
|
||||||
if self.len() > MAX_STAKE_HISTORY {
|
#[allow(clippy::trivially_copy_pass_by_ref)]
|
||||||
let oldest = *self.inner.keys().min().unwrap();
|
pub fn get(&self, epoch: &Epoch) -> Option<&StakeHistoryEntry> {
|
||||||
self.inner.remove(&oldest);
|
self.binary_search_by(|probe| epoch.cmp(&probe.0))
|
||||||
|
.ok()
|
||||||
|
.map(|index| &self[index].1)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add(&mut self, epoch: Epoch, entry: StakeHistoryEntry) {
|
||||||
|
match self.binary_search_by(|probe| epoch.cmp(&probe.0)) {
|
||||||
|
Ok(index) => (self.0)[index] = (epoch, entry),
|
||||||
|
Err(index) => (self.0).insert(index, (epoch, entry)),
|
||||||
}
|
}
|
||||||
|
(self.0).truncate(MAX_STAKE_HISTORY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Deref for StakeHistory {
|
impl Deref for StakeHistory {
|
||||||
type Target = HashMap<Epoch, StakeHistoryEntry>;
|
type Target = Vec<(Epoch, StakeHistoryEntry)>;
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
&self.inner
|
&self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +104,15 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
assert_eq!(stake_history.len(), MAX_STAKE_HISTORY);
|
assert_eq!(stake_history.len(), MAX_STAKE_HISTORY);
|
||||||
assert_eq!(*stake_history.keys().min().unwrap(), 1);
|
assert_eq!(stake_history.iter().map(|entry| entry.0).min().unwrap(), 1);
|
||||||
|
assert_eq!(stake_history.get(&0), None);
|
||||||
|
assert_eq!(
|
||||||
|
stake_history.get(&1),
|
||||||
|
Some(&StakeHistoryEntry {
|
||||||
|
activating: 1,
|
||||||
|
..StakeHistoryEntry::default()
|
||||||
|
})
|
||||||
|
);
|
||||||
// verify the account can hold a full instance
|
// verify the account can hold a full instance
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
StakeHistory::from(&create_account(lamports, &stake_history)),
|
StakeHistory::from(&create_account(lamports, &stake_history)),
|
||||||
|
|
Loading…
Reference in New Issue