solana_runtime/
stake_history.rs1use std::{
4 ops::{Deref, DerefMut},
5 sync::Arc,
6};
7
8#[derive(Default, Clone, PartialEq, Eq, Debug, Deserialize, Serialize, AbiExample)]
10pub struct StakeHistory(Arc<StakeHistoryInner>);
11
12impl Deref for StakeHistory {
13 type Target = StakeHistoryInner;
14 fn deref(&self) -> &Self::Target {
15 &self.0
16 }
17}
18
19impl DerefMut for StakeHistory {
20 fn deref_mut(&mut self) -> &mut Self::Target {
21 Arc::make_mut(&mut self.0)
22 }
23}
24
25type StakeHistoryInner = solana_sdk::stake_history::StakeHistory;
27
28#[cfg(test)]
29mod tests {
30 use {super::*, solana_sdk::stake_history::StakeHistoryEntry};
31
32 fn rand_stake_history_entry() -> StakeHistoryEntry {
33 StakeHistoryEntry {
34 effective: rand::random(),
35 activating: rand::random(),
36 deactivating: rand::random(),
37 }
38 }
39
40 #[test]
42 fn test_stake_history_is_cow() {
43 let mut stake_history = StakeHistory::default();
44 (100..109).for_each(|epoch| {
45 let entry = rand_stake_history_entry();
46 stake_history.add(epoch, entry);
47 });
48
49 {
52 let stake_history2 = stake_history.clone();
53 assert_eq!(stake_history, stake_history2);
54 assert!(
55 Arc::ptr_eq(&stake_history.0, &stake_history2.0),
56 "Inner Arc must point to the same underlying instance"
57 );
58 assert!(
59 std::ptr::eq(stake_history.deref(), stake_history2.deref()),
60 "Deref must point to the same underlying instance"
61 );
62 }
63
64 {
67 let mut stake_history2 = stake_history.clone();
68 assert_eq!(stake_history, stake_history2);
69 (200..209).for_each(|epoch| {
70 let entry = rand_stake_history_entry();
71 stake_history2.add(epoch, entry);
72 });
73 assert_ne!(stake_history, stake_history2);
74 assert!(
75 !Arc::ptr_eq(&stake_history.0, &stake_history2.0),
76 "Inner Arc must point to a different underlying instance"
77 );
78 assert!(
79 !std::ptr::eq(stake_history.deref(), stake_history2.deref()),
80 "Deref must point to a different underlying instance"
81 );
82 }
83 }
84
85 #[test]
87 fn test_stake_history_serde() {
88 let mut stake_history_outer = StakeHistory::default();
89 let mut stake_history_inner = StakeHistoryInner::default();
90 (2134..).take(11).for_each(|epoch| {
91 let entry = rand_stake_history_entry();
92 stake_history_outer.add(epoch, entry.clone());
93 stake_history_inner.add(epoch, entry);
94 });
95
96 assert_eq!(
98 bincode::serialize(&stake_history_outer).unwrap(),
99 bincode::serialize(&stake_history_inner).unwrap(),
100 );
101
102 {
105 let data = bincode::serialize(&stake_history_outer).unwrap();
106 let deserialized_inner: StakeHistoryInner = bincode::deserialize(&data).unwrap();
107 assert_eq!(&deserialized_inner, stake_history_outer.deref());
108 }
109
110 {
113 let data = bincode::serialize(&stake_history_inner).unwrap();
114 let deserialized_outer: StakeHistory = bincode::deserialize(&data).unwrap();
115 assert_eq!(deserialized_outer.deref(), &stake_history_inner);
116 }
117 }
118}