solana_sysvar/epoch_rewards.rs
1//! Epoch rewards for current epoch
2//!
3//! The _epoch rewards_ sysvar provides access to the [`EpochRewards`] type,
4//! which tracks whether the rewards period (including calculation and
5//! distribution) is in progress, as well as the details needed to resume
6//! distribution when starting from a snapshot during the rewards period. The
7//! sysvar is repopulated at the start of the first block of each epoch.
8//! Therefore, the sysvar contains data about the current epoch until a new
9//! epoch begins. Fields in the sysvar include:
10//! - distribution starting block height
11//! - the number of partitions in the distribution
12//! - the parent-blockhash seed used to generate the partition hasher
13//! - the total rewards points calculated for the epoch
14//! - total rewards for epoch, in lamports
15//! - rewards for the epoch distributed so far, in lamports
16//! - whether the rewards period is active
17//!
18//! [`EpochRewards`] implements [`crate::Sysvar::get`] and can be loaded efficiently without
19//! passing the sysvar account ID to the program.
20//!
21//! See also the Solana [documentation on the epoch rewards sysvar][sdoc].
22//!
23//! [sdoc]: https://docs.solanalabs.com/runtime/sysvars#epochrewards
24//!
25//! # Examples
26//!
27//! Accessing via on-chain program directly:
28//!
29//! ```no_run
30//! # use solana_account_info::AccountInfo;
31//! # use solana_epoch_rewards::EpochRewards;
32//! # use solana_msg::msg;
33//! # use solana_program_error::{ProgramError, ProgramResult};
34//! # use solana_pubkey::Pubkey;
35//! # use solana_sysvar::Sysvar;
36//! # use solana_sdk_ids::sysvar::epoch_rewards;
37//! fn process_instruction(
38//! program_id: &Pubkey,
39//! accounts: &[AccountInfo],
40//! instruction_data: &[u8],
41//! ) -> ProgramResult {
42//!
43//! let epoch_rewards = EpochRewards::get()?;
44//! msg!("epoch_rewards: {:#?}", epoch_rewards);
45//!
46//! Ok(())
47//! }
48//! #
49//! # use solana_sysvar_id::SysvarId;
50//! # let p = EpochRewards::id();
51//! # let l = &mut 1559040;
52//! # let epoch_rewards = EpochRewards {
53//! # distribution_starting_block_height: 42,
54//! # total_rewards: 100,
55//! # distributed_rewards: 10,
56//! # active: true,
57//! # ..EpochRewards::default()
58//! # };
59//! # let mut d: Vec<u8> = bincode::serialize(&epoch_rewards).unwrap();
60//! # let a = AccountInfo::new(&p, false, false, l, &mut d, &p, false);
61//! # let accounts = &[a.clone(), a];
62//! # process_instruction(
63//! # &Pubkey::new_unique(),
64//! # accounts,
65//! # &[],
66//! # )?;
67//! # Ok::<(), ProgramError>(())
68//! ```
69//!
70//! Accessing via on-chain program's account parameters:
71//!
72//! ```
73//! # use solana_account_info::{AccountInfo, next_account_info};
74//! # use solana_epoch_rewards::EpochRewards;
75//! # use solana_msg::msg;
76//! # use solana_program_error::{ProgramError, ProgramResult};
77//! # use solana_pubkey::Pubkey;
78//! # use solana_sdk_ids::sysvar::epoch_rewards;
79//! #
80//! fn process_instruction(
81//! program_id: &Pubkey,
82//! accounts: &[AccountInfo],
83//! instruction_data: &[u8],
84//! ) -> ProgramResult {
85//! let account_info_iter = &mut accounts.iter();
86//! let epoch_rewards_account_info = next_account_info(account_info_iter)?;
87//!
88//! assert!(epoch_rewards::check_id(epoch_rewards_account_info.key));
89//!
90//! let epoch_rewards: EpochRewards =
91//! wincode::deserialize(&epoch_rewards_account_info.data.borrow())
92//! .map_err(|_| ProgramError::InvalidArgument)?;
93//! msg!("epoch_rewards: {:#?}", epoch_rewards);
94//!
95//! Ok(())
96//! }
97//! #
98//! # use solana_sysvar_id::SysvarId;
99//! # let p = EpochRewards::id();
100//! # let l = &mut 1559040;
101//! # let epoch_rewards = EpochRewards {
102//! # distribution_starting_block_height: 42,
103//! # total_rewards: 100,
104//! # distributed_rewards: 10,
105//! # active: true,
106//! # ..EpochRewards::default()
107//! # };
108//! # let mut d: Vec<u8> = bincode::serialize(&epoch_rewards).unwrap();
109//! # let a = AccountInfo::new(&p, false, false, l, &mut d, &p, false);
110//! # let accounts = &[a.clone(), a];
111//! # process_instruction(
112//! # &Pubkey::new_unique(),
113//! # accounts,
114//! # &[],
115//! # )?;
116//! # Ok::<(), ProgramError>(())
117//! ```
118//!
119//! Accessing via the RPC client:
120//!
121//! ```
122//! # use solana_epoch_rewards::EpochRewards;
123//! # use solana_example_mocks::solana_account;
124//! # use solana_example_mocks::solana_rpc_client;
125//! # use solana_rpc_client::rpc_client::RpcClient;
126//! # use solana_account::Account;
127//! # use solana_sdk_ids::sysvar::epoch_rewards;
128//! # use anyhow::Result;
129//! #
130//! fn print_sysvar_epoch_rewards(client: &RpcClient) -> Result<()> {
131//! # let epoch_rewards = EpochRewards {
132//! # distribution_starting_block_height: 42,
133//! # total_rewards: 100,
134//! # distributed_rewards: 10,
135//! # active: true,
136//! # ..EpochRewards::default()
137//! # };
138//! # let data: Vec<u8> = bincode::serialize(&epoch_rewards)?;
139//! # client.set_get_account_response(epoch_rewards::ID, Account {
140//! # lamports: 1120560,
141//! # data,
142//! # owner: solana_sdk_ids::system_program::ID,
143//! # executable: false,
144//! # });
145//! #
146//! let epoch_rewards = client.get_account(&epoch_rewards::ID)?;
147//! let data: EpochRewards = bincode::deserialize(&epoch_rewards.data)?;
148//!
149//! Ok(())
150//! }
151//! #
152//! # let client = RpcClient::new(String::new());
153//! # print_sysvar_epoch_rewards(&client)?;
154//! #
155//! # Ok::<(), anyhow::Error>(())
156//! ```
157
158#[cfg(feature = "bincode")]
159#[allow(deprecated)]
160use crate::SysvarSerialize;
161pub use {
162 solana_epoch_rewards::{EpochRewards, SIZE},
163 solana_sdk_ids::sysvar::epoch_rewards::{check_id, id, ID},
164};
165
166#[cfg(feature = "bincode")]
167#[allow(deprecated)]
168impl SysvarSerialize for EpochRewards {}