Skip to content

Commit

Permalink
Make StakeHistory clone-on-write (solana-labs#21573)
Browse files Browse the repository at this point in the history
  • Loading branch information
brooksprumo authored Dec 3, 2021
1 parent 1430b58 commit 46fe561
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 2 deletions.
1 change: 1 addition & 0 deletions runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ pub mod snapshot_package;
pub mod snapshot_utils;
pub mod sorted_storages;
pub mod stake_delegations;
pub mod stake_history;
pub mod stake_weighted_timestamp;
pub mod stakes;
pub mod status_cache;
Expand Down
2 changes: 1 addition & 1 deletion runtime/src/serde_snapshot/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ mod test_bank_serialize {

// This some what long test harness is required to freeze the ABI of
// Bank's serialization due to versioned nature
#[frozen_abi(digest = "FBhQnLvFHaCkXN8ZL8MaR6yQUhLgyvWqdoFeBRwsmbBo")]
#[frozen_abi(digest = "Fv5AFJSnZi9sssiE7Jn8bH2iTPnqu3UNc3np62r1sTsr")]
#[derive(Serialize, AbiExample)]
pub struct BankAbiTestWrapperFuture {
#[serde(serialize_with = "wrapper_future")]
Expand Down
84 changes: 84 additions & 0 deletions runtime/src/stake_history.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
//! This module implements clone-on-write semantics for the SDK's `StakeHistory` to reduce
//! unnecessary cloning of the underlying vector.
use std::{
ops::{Deref, DerefMut},
sync::Arc,
};

/// The SDK's stake history with clone-on-write semantics
#[derive(Default, Clone, PartialEq, 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)
}
}

/// The inner type, which is the SDK's stake history
type StakeHistoryInner = solana_sdk::stake_history::StakeHistory;

#[cfg(test)]
mod tests {
use super::*;
use 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);
});

// Test: Clone the stake history and **do not modify**. Assert the underlying instances
// are the same.
{
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"
);
}

// Test: Clone the stake history and then modify. Assert the underlying instances are
// unique.
{
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"
);
}
}
}
2 changes: 1 addition & 1 deletion runtime/src/stakes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use {
crate::{
stake_delegations::StakeDelegations,
stake_history::StakeHistory,
vote_account::{VoteAccount, VoteAccounts, VoteAccountsHashMap},
},
rayon::{
Expand All @@ -17,7 +18,6 @@ use {
self,
state::{Delegation, StakeActivationStatus, StakeState},
},
stake_history::StakeHistory,
},
solana_stake_program::stake_state,
solana_vote_program::vote_state::VoteState,
Expand Down

0 comments on commit 46fe561

Please sign in to comment.