diff --git a/sdk/program/src/sysvar/mod.rs b/sdk/program/src/sysvar/mod.rs
index 2376b371a528eb..fc3becac1b5d1a 100644
--- a/sdk/program/src/sysvar/mod.rs
+++ b/sdk/program/src/sysvar/mod.rs
@@ -249,6 +249,35 @@ macro_rules! impl_sysvar_get {
};
}
+/// Handler for retrieving a slice of sysvar data from the `sol_get_sysvar`
+/// syscall.
+fn get_sysvar(
+ dst: &mut [u8],
+ sysvar_id: &Pubkey,
+ offset: u64,
+ length: u64,
+) -> Result<(), ProgramError> {
+ // Check that the provided destination buffer is large enough to hold the
+ // requested data.
+ if dst.len() < length as usize {
+ return Err(ProgramError::InvalidArgument);
+ }
+
+ let sysvar_id = sysvar_id as *const _ as *const u8;
+ let var_addr = dst as *mut _ as *mut u8;
+
+ #[cfg(target_os = "solana")]
+ let result = unsafe { crate::syscalls::sol_get_sysvar(sysvar_id, var_addr, offset, length) };
+
+ #[cfg(not(target_os = "solana"))]
+ let result = crate::program_stubs::sol_get_sysvar(sysvar_id, var_addr, offset, length);
+
+ match result {
+ crate::entrypoint::SUCCESS => Ok(()),
+ e => Err(e.into()),
+ }
+}
+
#[cfg(test)]
mod tests {
use {
diff --git a/sdk/program/src/sysvar/slot_hashes.rs b/sdk/program/src/sysvar/slot_hashes.rs
index 18971dc48823c2..9d66fab235b585 100644
--- a/sdk/program/src/sysvar/slot_hashes.rs
+++ b/sdk/program/src/sysvar/slot_hashes.rs
@@ -46,7 +46,17 @@
//! ```
pub use crate::slot_hashes::SlotHashes;
-use crate::{account_info::AccountInfo, program_error::ProgramError, sysvar::Sysvar};
+use {
+ crate::{
+ account_info::AccountInfo,
+ clock::Slot,
+ hash::Hash,
+ program_error::ProgramError,
+ slot_hashes::MAX_ENTRIES,
+ sysvar::{get_sysvar, Sysvar, SysvarId},
+ },
+ bytemuck::{Pod, Zeroable},
+};
crate::declare_sysvar_id!("SysvarS1otHashes111111111111111111111111111", SlotHashes);
@@ -62,13 +72,109 @@ impl Sysvar for SlotHashes {
}
}
+#[derive(Copy, Clone, Default, Pod, Zeroable)]
+#[repr(C)]
+struct PodSlotHash {
+ slot: Slot,
+ hash: Hash,
+}
+
+/// API for querying the `SlotHashes` sysvar.
+pub struct SlotHashesSysvar;
+
+impl SlotHashesSysvar {
+ /// Get a value from the sysvar entries by its key.
+ /// Returns `None` if the key is not found.
+ pub fn get(slot: &Slot) -> Result