Skip to content

Commit 46fe561

Browse files
authored
Make StakeHistory clone-on-write (solana-labs#21573)
1 parent 1430b58 commit 46fe561

File tree

4 files changed

+87
-2
lines changed

4 files changed

+87
-2
lines changed

runtime/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ pub mod snapshot_package;
4949
pub mod snapshot_utils;
5050
pub mod sorted_storages;
5151
pub mod stake_delegations;
52+
pub mod stake_history;
5253
pub mod stake_weighted_timestamp;
5354
pub mod stakes;
5455
pub mod status_cache;

runtime/src/serde_snapshot/tests.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ mod test_bank_serialize {
312312

313313
// This some what long test harness is required to freeze the ABI of
314314
// Bank's serialization due to versioned nature
315-
#[frozen_abi(digest = "FBhQnLvFHaCkXN8ZL8MaR6yQUhLgyvWqdoFeBRwsmbBo")]
315+
#[frozen_abi(digest = "Fv5AFJSnZi9sssiE7Jn8bH2iTPnqu3UNc3np62r1sTsr")]
316316
#[derive(Serialize, AbiExample)]
317317
pub struct BankAbiTestWrapperFuture {
318318
#[serde(serialize_with = "wrapper_future")]

runtime/src/stake_history.rs

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
//! This module implements clone-on-write semantics for the SDK's `StakeHistory` to reduce
2+
//! unnecessary cloning of the underlying vector.
3+
use std::{
4+
ops::{Deref, DerefMut},
5+
sync::Arc,
6+
};
7+
8+
/// The SDK's stake history with clone-on-write semantics
9+
#[derive(Default, Clone, PartialEq, Debug, Deserialize, Serialize, AbiExample)]
10+
pub struct StakeHistory(Arc<StakeHistoryInner>);
11+
12+
impl Deref for StakeHistory {
13+
type Target = StakeHistoryInner;
14+
fn deref(&self) -> &Self::Target {
15+
&self.0
16+
}
17+
}
18+
19+
impl DerefMut for StakeHistory {
20+
fn deref_mut(&mut self) -> &mut Self::Target {
21+
Arc::make_mut(&mut self.0)
22+
}
23+
}
24+
25+
/// The inner type, which is the SDK's stake history
26+
type StakeHistoryInner = solana_sdk::stake_history::StakeHistory;
27+
28+
#[cfg(test)]
29+
mod tests {
30+
use super::*;
31+
use solana_sdk::stake_history::StakeHistoryEntry;
32+
33+
fn rand_stake_history_entry() -> StakeHistoryEntry {
34+
StakeHistoryEntry {
35+
effective: rand::random(),
36+
activating: rand::random(),
37+
deactivating: rand::random(),
38+
}
39+
}
40+
41+
#[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+
// Test: Clone the stake history and **do not modify**. Assert the underlying instances
50+
// are the same.
51+
{
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+
// Test: Clone the stake history and then modify. Assert the underlying instances are
65+
// unique.
66+
{
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+
}

runtime/src/stakes.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use {
44
crate::{
55
stake_delegations::StakeDelegations,
6+
stake_history::StakeHistory,
67
vote_account::{VoteAccount, VoteAccounts, VoteAccountsHashMap},
78
},
89
rayon::{
@@ -17,7 +18,6 @@ use {
1718
self,
1819
state::{Delegation, StakeActivationStatus, StakeState},
1920
},
20-
stake_history::StakeHistory,
2121
},
2222
solana_stake_program::stake_state,
2323
solana_vote_program::vote_state::VoteState,

0 commit comments

Comments
 (0)