solana_runtime/
stake_history.rsuse std::{
ops::{Deref, DerefMut},
sync::Arc,
};
#[derive(Default, Clone, PartialEq, Eq, Debug, Deserialize, Serialize, AbiExample)]
pub struct StakeHistory(Arc<StakeHistoryInner>);
impl Deref for StakeHistory {
type Target = StakeHistoryInner;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for StakeHistory {
fn deref_mut(&mut self) -> &mut Self::Target {
Arc::make_mut(&mut self.0)
}
}
type StakeHistoryInner = solana_sdk::stake_history::StakeHistory;
#[cfg(test)]
mod tests {
use {super::*, solana_sdk::stake_history::StakeHistoryEntry};
fn rand_stake_history_entry() -> StakeHistoryEntry {
StakeHistoryEntry {
effective: rand::random(),
activating: rand::random(),
deactivating: rand::random(),
}
}
#[test]
fn test_stake_history_is_cow() {
let mut stake_history = StakeHistory::default();
(100..109).for_each(|epoch| {
let entry = rand_stake_history_entry();
stake_history.add(epoch, entry);
});
{
let stake_history2 = stake_history.clone();
assert_eq!(stake_history, stake_history2);
assert!(
Arc::ptr_eq(&stake_history.0, &stake_history2.0),
"Inner Arc must point to the same underlying instance"
);
assert!(
std::ptr::eq(stake_history.deref(), stake_history2.deref()),
"Deref must point to the same underlying instance"
);
}
{
let mut stake_history2 = stake_history.clone();
assert_eq!(stake_history, stake_history2);
(200..209).for_each(|epoch| {
let entry = rand_stake_history_entry();
stake_history2.add(epoch, entry);
});
assert_ne!(stake_history, stake_history2);
assert!(
!Arc::ptr_eq(&stake_history.0, &stake_history2.0),
"Inner Arc must point to a different underlying instance"
);
assert!(
!std::ptr::eq(stake_history.deref(), stake_history2.deref()),
"Deref must point to a different underlying instance"
);
}
}
#[test]
fn test_stake_history_serde() {
let mut stake_history_outer = StakeHistory::default();
let mut stake_history_inner = StakeHistoryInner::default();
(2134..).take(11).for_each(|epoch| {
let entry = rand_stake_history_entry();
stake_history_outer.add(epoch, entry.clone());
stake_history_inner.add(epoch, entry);
});
assert_eq!(
bincode::serialize(&stake_history_outer).unwrap(),
bincode::serialize(&stake_history_inner).unwrap(),
);
{
let data = bincode::serialize(&stake_history_outer).unwrap();
let deserialized_inner: StakeHistoryInner = bincode::deserialize(&data).unwrap();
assert_eq!(&deserialized_inner, stake_history_outer.deref());
}
{
let data = bincode::serialize(&stake_history_inner).unwrap();
let deserialized_outer: StakeHistory = bincode::deserialize(&data).unwrap();
assert_eq!(deserialized_outer.deref(), &stake_history_inner);
}
}
}