solana_program/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 [`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_program::{
31//! # account_info::{AccountInfo, next_account_info},
32//! # entrypoint::ProgramResult,
33//! # msg,
34//! # program_error::ProgramError,
35//! # pubkey::Pubkey,
36//! # sysvar::epoch_rewards::{self, EpochRewards},
37//! # sysvar::Sysvar,
38//! # };
39//! #
40//! fn process_instruction(
41//! program_id: &Pubkey,
42//! accounts: &[AccountInfo],
43//! instruction_data: &[u8],
44//! ) -> ProgramResult {
45//!
46//! let epoch_rewards = EpochRewards::get()?;
47//! msg!("epoch_rewards: {:#?}", epoch_rewards);
48//!
49//! Ok(())
50//! }
51//! #
52//! # use solana_sysvar_id::SysvarId;
53//! # let p = EpochRewards::id();
54//! # let l = &mut 1559040;
55//! # let epoch_rewards = EpochRewards {
56//! # distribution_starting_block_height: 42,
57//! # total_rewards: 100,
58//! # distributed_rewards: 10,
59//! # active: true,
60//! # ..EpochRewards::default()
61//! # };
62//! # let mut d: Vec<u8> = bincode::serialize(&epoch_rewards).unwrap();
63//! # let a = AccountInfo::new(&p, false, false, l, &mut d, &p, false, 0);
64//! # let accounts = &[a.clone(), a];
65//! # process_instruction(
66//! # &Pubkey::new_unique(),
67//! # accounts,
68//! # &[],
69//! # )?;
70//! # Ok::<(), ProgramError>(())
71//! ```
72//!
73//! Accessing via on-chain program's account parameters:
74//!
75//! ```
76//! # use solana_program::{
77//! # account_info::{AccountInfo, next_account_info},
78//! # entrypoint::ProgramResult,
79//! # msg,
80//! # pubkey::Pubkey,
81//! # sysvar::epoch_rewards::{self, EpochRewards},
82//! # sysvar::Sysvar,
83//! # };
84//! # use solana_program::program_error::ProgramError;
85//! #
86//! fn process_instruction(
87//! program_id: &Pubkey,
88//! accounts: &[AccountInfo],
89//! instruction_data: &[u8],
90//! ) -> ProgramResult {
91//! let account_info_iter = &mut accounts.iter();
92//! let epoch_rewards_account_info = next_account_info(account_info_iter)?;
93//!
94//! assert!(epoch_rewards::check_id(epoch_rewards_account_info.key));
95//!
96//! let epoch_rewards = EpochRewards::from_account_info(epoch_rewards_account_info)?;
97//! msg!("epoch_rewards: {:#?}", epoch_rewards);
98//!
99//! Ok(())
100//! }
101//! #
102//! # use solana_sysvar_id::SysvarId;
103//! # let p = EpochRewards::id();
104//! # let l = &mut 1559040;
105//! # let epoch_rewards = EpochRewards {
106//! # distribution_starting_block_height: 42,
107//! # total_rewards: 100,
108//! # distributed_rewards: 10,
109//! # active: true,
110//! # ..EpochRewards::default()
111//! # };
112//! # let mut d: Vec<u8> = bincode::serialize(&epoch_rewards).unwrap();
113//! # let a = AccountInfo::new(&p, false, false, l, &mut d, &p, false, 0);
114//! # let accounts = &[a.clone(), a];
115//! # process_instruction(
116//! # &Pubkey::new_unique(),
117//! # accounts,
118//! # &[],
119//! # )?;
120//! # Ok::<(), ProgramError>(())
121//! ```
122//!
123//! Accessing via the RPC client:
124//!
125//! ```
126//! # use solana_program::example_mocks::solana_sdk;
127//! # use solana_program::example_mocks::solana_rpc_client;
128//! # use solana_sdk::account::Account;
129//! # use solana_rpc_client::rpc_client::RpcClient;
130//! # use solana_sdk::sysvar::epoch_rewards::{self, EpochRewards};
131//! # use anyhow::Result;
132//! #
133//! fn print_sysvar_epoch_rewards(client: &RpcClient) -> Result<()> {
134//! # let epoch_rewards = EpochRewards {
135//! # distribution_starting_block_height: 42,
136//! # total_rewards: 100,
137//! # distributed_rewards: 10,
138//! # active: true,
139//! # ..EpochRewards::default()
140//! # };
141//! # let data: Vec<u8> = bincode::serialize(&epoch_rewards)?;
142//! # client.set_get_account_response(epoch_rewards::ID, Account {
143//! # lamports: 1120560,
144//! # data,
145//! # owner: solana_sdk::system_program::ID,
146//! # executable: false,
147//! # rent_epoch: 307,
148//! # });
149//! #
150//! let epoch_rewards = client.get_account(&epoch_rewards::ID)?;
151//! let data: EpochRewards = bincode::deserialize(&epoch_rewards.data)?;
152//!
153//! Ok(())
154//! }
155//! #
156//! # let client = RpcClient::new(String::new());
157//! # print_sysvar_epoch_rewards(&client)?;
158//! #
159//! # Ok::<(), anyhow::Error>(())
160//! ```
161
162pub use crate::epoch_rewards::EpochRewards;
163use {
164 crate::{impl_sysvar_get, program_error::ProgramError, sysvar::Sysvar},
165 solana_sysvar_id::declare_sysvar_id,
166};
167
168declare_sysvar_id!("SysvarEpochRewards1111111111111111111111111", EpochRewards);
169
170impl Sysvar for EpochRewards {
171 impl_sysvar_get!(sol_get_epoch_rewards_sysvar);
172}