waffles_solana_program/sysvar/
slot_hashes.rs

1//! The most recent hashes of a slot's parent banks.
2//!
3//! The _slot hashes sysvar_ provides access to the [`SlotHashes`] type.
4//!
5//! The [`Sysvar::from_account_info`] and [`Sysvar::get`] methods always return
6//! [`ProgramError::UnsupportedSysvar`] because this sysvar account is too large
7//! to process on-chain. Thus this sysvar cannot be accessed on chain, though
8//! one can still use the [`SysvarId::id`], [`SysvarId::check_id`] and
9//! [`Sysvar::size_of`] methods in an on-chain program, and it can be accessed
10//! off-chain through RPC.
11//!
12//! [`SysvarId::id`]: crate::sysvar::SysvarId::id
13//! [`SysvarId::check_id`]: crate::sysvar::SysvarId::check_id
14//!
15//! # Examples
16//!
17//! Calling via the RPC client:
18//!
19//! ```
20//! # use solana_program::example_mocks::solana_sdk;
21//! # use solana_program::example_mocks::solana_rpc_client;
22//! # use solana_sdk::account::Account;
23//! # use solana_rpc_client::rpc_client::RpcClient;
24//! # use solana_sdk::sysvar::slot_hashes::{self, SlotHashes};
25//! # use anyhow::Result;
26//! #
27//! fn print_sysvar_slot_hashes(client: &RpcClient) -> Result<()> {
28//! #   client.set_get_account_response(slot_hashes::ID, Account {
29//! #       lamports: 1009200,
30//! #       data: vec![1, 0, 0, 0, 0, 0, 0, 0, 86, 190, 235, 7, 0, 0, 0, 0, 133, 242, 94, 158, 223, 253, 207, 184, 227, 194, 235, 27, 176, 98, 73, 3, 175, 201, 224, 111, 21, 65, 73, 27, 137, 73, 229, 19, 255, 192, 193, 126],
31//! #       owner: solana_sdk::system_program::ID,
32//! #       executable: false,
33//! #       rent_epoch: 307,
34//! # });
35//! #
36//!     let slot_hashes = client.get_account(&slot_hashes::ID)?;
37//!     let data: SlotHashes = bincode::deserialize(&slot_hashes.data)?;
38//!
39//!     Ok(())
40//! }
41//! #
42//! # let client = RpcClient::new(String::new());
43//! # print_sysvar_slot_hashes(&client)?;
44//! #
45//! # Ok::<(), anyhow::Error>(())
46//! ```
47
48pub use crate::slot_hashes::SlotHashes;
49use crate::{account_info::AccountInfo, program_error::ProgramError, sysvar::Sysvar};
50
51crate::declare_sysvar_id!("SysvarS1otHashes111111111111111111111111111", SlotHashes);
52
53impl Sysvar for SlotHashes {
54    // override
55    fn size_of() -> usize {
56        // hard-coded so that we don't have to construct an empty
57        20_488 // golden, update if MAX_ENTRIES changes
58    }
59    fn from_account_info(_account_info: &AccountInfo) -> Result<Self, ProgramError> {
60        // This sysvar is too large to bincode::deserialize in-program
61        Err(ProgramError::UnsupportedSysvar)
62    }
63}
64
65#[cfg(test)]
66mod tests {
67    use {
68        super::*,
69        crate::{clock::Slot, hash::Hash, slot_hashes::MAX_ENTRIES},
70    };
71
72    #[test]
73    fn test_size_of() {
74        assert_eq!(
75            SlotHashes::size_of(),
76            bincode::serialized_size(
77                &(0..MAX_ENTRIES)
78                    .map(|slot| (slot as Slot, Hash::default()))
79                    .collect::<SlotHashes>()
80            )
81            .unwrap() as usize
82        );
83    }
84}