Skip to content

Commit

Permalink
Extract sysvar crate, including program_stubs.rs (solana-labs#3680)
Browse files Browse the repository at this point in the history
* minimise solana_program usage in sysvar and program_stubs modules

* move solana_program::stake_history contents into solana_program::sysvar

* extract sysvar crate, including program_stubs.rs

* remove trailing whitespace

* update program_stubs path in nits.sh

* missing re-export

* missing frozen-abi support

* feature activation fixes

* remove unused dev dep

* update digest

* fix sbf build

* fix re-export

* missing ;

* fmt

* inline re-export for cleaner docs

* make serde and bincode optional in solana-sysvar

* make bytemuck optional in sysvar crate

* Apply suggestions

Co-authored-by: Jon C <me@jonc.dev>

* remove superfluous ::

* remove unnecessary feature gating

* move frozen-abi activation to the right file

* remove message dep from the tests that were moved

* move those tests back

* add deprecation

* remove unnecessary lifetimes

---------

Co-authored-by: Jon C <me@jonc.dev>
  • Loading branch information
kevinheavey and joncinque authored Nov 19, 2024
1 parent 926c009 commit aeb5518
Show file tree
Hide file tree
Showing 28 changed files with 808 additions and 471 deletions.
48 changes: 48 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ members = [
"sdk/slot-hashes",
"sdk/slot-history",
"sdk/stable-layout",
"sdk/sysvar",
"sdk/sysvar-id",
"sdk/time-utils",
"sdk/transaction-context",
Expand Down Expand Up @@ -545,6 +546,7 @@ solana-svm-conformance = { path = "svm-conformance", version = "=2.2.0" }
solana-svm-rent-collector = { path = "svm-rent-collector", version = "=2.2.0" }
solana-svm-transaction = { path = "svm-transaction", version = "=2.2.0" }
solana-system-program = { path = "programs/system", version = "=2.2.0" }
solana-sysvar = { path = "sdk/sysvar", version = "=2.2.0" }
solana-sysvar-id = { path = "sdk/sysvar-id", version = "=2.2.0" }
solana-test-validator = { path = "test-validator", version = "=2.2.0" }
solana-thin-client = { path = "thin-client", version = "=2.2.0" }
Expand Down
2 changes: 1 addition & 1 deletion ci/nits.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ declare print_free_tree=(
':^sdk/cargo-build-sbf/**.rs'
':^sdk/msg/src/lib.rs'
':^sdk/program-option/src/lib.rs'
':^sdk/program/src/program_stubs.rs'
':^sdk/pubkey/src/lib.rs'
':^sdk/sysvar/src/program_stubs.rs'
':programs/**.rs'
':^**bin**.rs'
':^**bench**.rs'
Expand Down
36 changes: 36 additions & 0 deletions programs/sbf/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion runtime/src/bank/serde_snapshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,7 @@ mod tests {
#[cfg_attr(
feature = "frozen-abi",
derive(AbiExample),
frozen_abi(digest = "EEpMTdTGYGixHBVVtQM2yUJirUiMFMWxNdhABfdscpYW")
frozen_abi(digest = "DVmmgXfBgsFRjX2Yun7Wcyt2gafnMVHvTRXBVUHeL3NC")
)]
#[derive(Serialize)]
pub struct BankAbiTestWrapper {
Expand Down
1 change: 1 addition & 0 deletions sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ hex = { workspace = true }
solana-logger = { workspace = true }
solana-program = { workspace = true, features = ["dev-context-only-utils"] }
solana-sdk = { path = ".", features = ["dev-context-only-utils"] }
solana-sysvar = { workspace = true, features = ["dev-context-only-utils"] }
static_assertions = { workspace = true }
tiny-bip39 = { workspace = true }

Expand Down
2 changes: 1 addition & 1 deletion sdk/benches/serialize_instructions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use {
message::{Message, SanitizedMessage},
pubkey::{self, Pubkey},
reserved_account_keys::ReservedAccountKeys,
sysvar::instructions::{self, construct_instructions_data},
},
solana_sysvar::instructions::{self, construct_instructions_data},
test::Bencher,
};

Expand Down
5 changes: 4 additions & 1 deletion sdk/program/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ solana-short-vec = { workspace = true }
solana-slot-hashes = { workspace = true, features = ["serde", "sysvar"] }
solana-slot-history = { workspace = true, features = ["serde", "sysvar"] }
solana-stable-layout = { workspace = true }
solana-sysvar = { workspace = true, features = ["bincode", "bytemuck"] }
solana-sysvar-id = { workspace = true }
thiserror = { workspace = true }

Expand Down Expand Up @@ -120,6 +121,7 @@ itertools = { workspace = true }
serde_json = { workspace = true }
serial_test = { workspace = true }
solana-pubkey = { workspace = true, features = ["dev-context-only-utils"] }
solana-sysvar = { workspace = true, features = ["dev-context-only-utils"] }
static_assertions = { workspace = true }
test-case = { workspace = true }

Expand Down Expand Up @@ -151,7 +153,8 @@ frozen-abi = [
"solana-instruction/frozen-abi",
"solana-pubkey/frozen-abi",
"solana-rent/frozen-abi",
"solana-short-vec/frozen-abi"
"solana-short-vec/frozen-abi",
"solana-sysvar/frozen-abi"
]

[lints]
Expand Down
4 changes: 3 additions & 1 deletion sdk/program/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,6 @@ pub mod message;
pub mod nonce;
pub mod program;
pub mod program_error;
pub mod program_stubs;
pub mod program_utils;
pub mod secp256k1_program;
pub mod slot_hashes;
Expand Down Expand Up @@ -540,6 +539,8 @@ pub use solana_serialize_utils as serialize_utils;
pub use solana_short_vec as short_vec;
#[deprecated(since = "2.1.0", note = "Use `solana-stable-layout` crate instead")]
pub use solana_stable_layout as stable_layout;
#[cfg(not(target_os = "solana"))]
pub use solana_sysvar::program_stubs;
#[cfg(target_arch = "wasm32")]
pub use wasm_bindgen::prelude::wasm_bindgen;
pub use {
Expand All @@ -552,6 +553,7 @@ pub use {
entrypoint_no_alloc,
},
solana_program_option as program_option, solana_pubkey as pubkey, solana_rent as rent,
solana_sysvar::impl_sysvar_get,
};
/// The [config native program][np].
///
Expand Down
2 changes: 1 addition & 1 deletion sdk/program/src/message/sanitized.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ use {
pubkey::Pubkey,
secp256k1_program,
solana_program::{system_instruction::SystemInstruction, system_program},
sysvar::instructions::{BorrowedAccountMeta, BorrowedInstruction},
},
solana_sanitize::Sanitize,
solana_sysvar::instructions::{BorrowedAccountMeta, BorrowedInstruction},
std::{borrow::Cow, collections::HashSet, convert::TryFrom},
};

Expand Down
133 changes: 6 additions & 127 deletions sdk/program/src/stake_history.rs
Original file line number Diff line number Diff line change
@@ -1,127 +1,6 @@
//! A type to hold data for the [`StakeHistory` sysvar][sv].
//!
//! [sv]: https://docs.solanalabs.com/runtime/sysvars#stakehistory
//!
//! The sysvar ID is declared in [`sysvar::stake_history`].
//!
//! [`sysvar::stake_history`]: crate::sysvar::stake_history
pub use solana_clock::Epoch;
use std::ops::Deref;

pub const MAX_ENTRIES: usize = 512; // it should never take as many as 512 epochs to warm up or cool down

#[repr(C)]
#[cfg_attr(feature = "frozen-abi", derive(AbiExample))]
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Default, Clone)]
pub struct StakeHistoryEntry {
pub effective: u64, // effective stake at this epoch
pub activating: u64, // sum of portion of stakes not fully warmed up
pub deactivating: u64, // requested to be cooled down, not fully deactivated yet
}

impl StakeHistoryEntry {
pub fn with_effective(effective: u64) -> Self {
Self {
effective,
..Self::default()
}
}

pub fn with_effective_and_activating(effective: u64, activating: u64) -> Self {
Self {
effective,
activating,
..Self::default()
}
}

pub fn with_deactivating(deactivating: u64) -> Self {
Self {
effective: deactivating,
deactivating,
..Self::default()
}
}
}

impl std::ops::Add for StakeHistoryEntry {
type Output = StakeHistoryEntry;
fn add(self, rhs: StakeHistoryEntry) -> Self::Output {
Self {
effective: self.effective.saturating_add(rhs.effective),
activating: self.activating.saturating_add(rhs.activating),
deactivating: self.deactivating.saturating_add(rhs.deactivating),
}
}
}

#[repr(C)]
#[cfg_attr(feature = "frozen-abi", derive(AbiExample))]
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Default, Clone)]
pub struct StakeHistory(Vec<(Epoch, StakeHistoryEntry)>);

impl StakeHistory {
pub fn get(&self, epoch: Epoch) -> Option<&StakeHistoryEntry> {
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_ENTRIES);
}
}

impl Deref for StakeHistory {
type Target = Vec<(Epoch, StakeHistoryEntry)>;
fn deref(&self) -> &Self::Target {
&self.0
}
}

pub trait StakeHistoryGetEntry {
fn get_entry(&self, epoch: Epoch) -> Option<StakeHistoryEntry>;
}

impl StakeHistoryGetEntry for StakeHistory {
fn get_entry(&self, epoch: Epoch) -> Option<StakeHistoryEntry> {
self.binary_search_by(|probe| epoch.cmp(&probe.0))
.ok()
.map(|index| self[index].1.clone())
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_stake_history() {
let mut stake_history = StakeHistory::default();

for i in 0..MAX_ENTRIES as u64 + 1 {
stake_history.add(
i,
StakeHistoryEntry {
activating: i,
..StakeHistoryEntry::default()
},
);
}
assert_eq!(stake_history.len(), MAX_ENTRIES);
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()
})
);
}
}
pub use {
crate::sysvar::stake_history::{
StakeHistory, StakeHistoryEntry, StakeHistoryGetEntry, MAX_ENTRIES,
},
solana_clock::Epoch,
};
12 changes: 12 additions & 0 deletions sdk/program/src/sysvar.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#[deprecated(since = "2.1.0", note = "Use `solana-sysvar-id` crate instead")]
pub use solana_sysvar_id::{declare_deprecated_sysvar_id, declare_sysvar_id, SysvarId};
#[deprecated(since = "2.2.0", note = "Use `solana-sysvar` crate instead")]
#[allow(deprecated)]
pub use {
solana_sdk_ids::sysvar::{check_id, id, ID},
solana_sysvar::{
clock, epoch_rewards, epoch_schedule, fees, instructions, is_sysvar_id, last_restart_slot,
recent_blockhashes, rent, rewards, slot_hashes, slot_history, stake_history, Sysvar,
ALL_IDS,
},
};
Loading

0 comments on commit aeb5518

Please sign in to comment.