solana_accounts_db/
stake_rewards.rs1use {
4 crate::{
5 is_zero_lamport::IsZeroLamport,
6 storable_accounts::{AccountForStorage, StorableAccounts},
7 },
8 solana_account::{AccountSharedData, ReadableAccount},
9 solana_clock::Slot,
10 solana_pubkey::Pubkey,
11 solana_reward_info::RewardInfo,
12};
13
14#[cfg_attr(feature = "frozen-abi", derive(AbiExample))]
15#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
16pub struct StakeReward {
17 pub stake_pubkey: Pubkey,
18 pub stake_reward_info: RewardInfo,
19 pub stake_account: AccountSharedData,
20}
21
22impl StakeReward {
23 pub fn get_stake_reward(&self) -> i64 {
24 self.stake_reward_info.lamports
25 }
26}
27
28impl IsZeroLamport for StakeReward {
29 fn is_zero_lamport(&self) -> bool {
30 self.stake_account.lamports() == 0
31 }
32}
33
34impl<'a> StorableAccounts<'a> for (Slot, &'a [StakeReward]) {
36 fn account<Ret>(
37 &self,
38 index: usize,
39 mut callback: impl for<'local> FnMut(AccountForStorage<'local>) -> Ret,
40 ) -> Ret {
41 let entry = &self.1[index];
42 callback((&self.1[index].stake_pubkey, &entry.stake_account).into())
43 }
44 fn is_zero_lamport(&self, index: usize) -> bool {
45 self.1[index].is_zero_lamport()
46 }
47 fn data_len(&self, index: usize) -> usize {
48 self.1[index].stake_account.data().len()
49 }
50 fn pubkey(&self, index: usize) -> &Pubkey {
51 &self.1[index].stake_pubkey
52 }
53 fn slot(&self, _index: usize) -> Slot {
54 self.target_slot()
56 }
57 fn target_slot(&self) -> Slot {
58 self.0
59 }
60 fn len(&self) -> usize {
61 self.1.len()
62 }
63}
64
65#[cfg(feature = "dev-context-only-utils")]
66use {
67 rand::Rng, solana_account::WritableAccount, solana_keypair::Keypair, solana_rent::Rent,
68 solana_signer::Signer, solana_stake_program::stake_state, solana_vote_program::vote_state,
69};
70
71#[cfg(feature = "dev-context-only-utils")]
73impl StakeReward {
74 pub fn new_random() -> Self {
75 let mut rng = rand::thread_rng();
76
77 let rent = Rent::free();
78
79 let validator_pubkey = solana_pubkey::new_rand();
80 let validator_stake_lamports = 20;
81 let validator_staking_keypair = Keypair::new();
82 let validator_voting_keypair = Keypair::new();
83
84 let validator_vote_account = vote_state::create_account(
85 &validator_voting_keypair.pubkey(),
86 &validator_pubkey,
87 10,
88 validator_stake_lamports,
89 );
90
91 let reward_lamports: i64 = rng.gen_range(1..200);
92 let validator_stake_account = stake_state::create_account(
93 &validator_staking_keypair.pubkey(),
94 &validator_voting_keypair.pubkey(),
95 &validator_vote_account,
96 &rent,
97 validator_stake_lamports + reward_lamports as u64,
98 );
99
100 Self {
101 stake_pubkey: Pubkey::new_unique(),
102 stake_reward_info: RewardInfo {
103 reward_type: solana_reward_info::RewardType::Staking,
104 lamports: reward_lamports,
105 post_balance: 0, commission: Some(0), },
108
109 stake_account: validator_stake_account,
110 }
111 }
112
113 pub fn credit(&mut self, amount: u64) {
114 self.stake_reward_info.lamports = amount as i64;
115 self.stake_reward_info.post_balance += amount;
116 self.stake_account.checked_add_lamports(amount).unwrap();
117 }
118}